• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * cl_3a_image_processor.cpp - CL 3A image processor
3  *
4  *  Copyright (c) 2015 Intel Corporation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Author: Wind Yuan <feng.yuan@intel.com>
19  */
20 #include "cl_3a_image_processor.h"
21 #include "cl_context.h"
22 #include "cl_csc_handler.h"
23 #include "cl_bayer_pipe_handler.h"
24 #include "cl_yuv_pipe_handler.h"
25 #if ENABLE_YEENR_HANDLER
26 #include "cl_ee_handler.h"
27 #endif
28 #include "cl_tnr_handler.h"
29 #include "cl_tonemapping_handler.h"
30 #include "cl_newtonemapping_handler.h"
31 #include "cl_bayer_basic_handler.h"
32 
33 #define XCAM_CL_3A_IMAGE_MAX_POOL_SIZE 6
34 
35 namespace XCam {
36 
CL3aImageProcessor()37 CL3aImageProcessor::CL3aImageProcessor ()
38     : CLImageProcessor ("CL3aImageProcessor")
39     , _output_fourcc (V4L2_PIX_FMT_NV12)
40     , _3a_stats_bits (8)
41     , _pipeline_profile (BasicPipelineProfile)
42     , _capture_stage (TonemappingStage)
43     , _wdr_mode (WDRdisabled)
44     , _tnr_mode (0)
45     , _enable_gamma (true)
46     , _enable_macc (true)
47     , _snr_mode (0)
48 {
49     keep_attached_buf (true);
50     XCAM_LOG_DEBUG ("CL3aImageProcessor constructed");
51 }
52 
~CL3aImageProcessor()53 CL3aImageProcessor::~CL3aImageProcessor ()
54 {
55     XCAM_LOG_DEBUG ("CL3aImageProcessor destructed");
56 }
57 
58 void
set_stats_callback(const SmartPtr<StatsCallback> & callback)59 CL3aImageProcessor::set_stats_callback (const SmartPtr<StatsCallback> &callback)
60 {
61     XCAM_ASSERT (callback.ptr ());
62     _stats_callback = callback;
63 }
64 
65 bool
set_output_format(uint32_t fourcc)66 CL3aImageProcessor::set_output_format (uint32_t fourcc)
67 {
68     XCAM_FAIL_RETURN (
69         WARNING,
70         V4L2_PIX_FMT_NV12 == fourcc,
71         false,
72         "cl 3a processor doesn't support output format: %s",
73         xcam_fourcc_to_string (fourcc));
74 
75     _output_fourcc = fourcc;
76     return true;
77 }
78 
79 bool
set_capture_stage(CaptureStage capture_stage)80 CL3aImageProcessor::set_capture_stage (CaptureStage capture_stage)
81 {
82     _capture_stage = capture_stage;
83     return true;
84 }
85 
86 bool
set_3a_stats_bits(uint32_t bits)87 CL3aImageProcessor::set_3a_stats_bits (uint32_t bits)
88 {
89     switch (bits) {
90     case 8:
91     case 12:
92         _3a_stats_bits = bits;
93         break;
94     default:
95         XCAM_LOG_WARNING ("cl image processor 3a stats doesn't support %d-bits", bits);
96         return false;
97     }
98     return true;
99 }
100 
101 bool
can_process_result(SmartPtr<X3aResult> & result)102 CL3aImageProcessor::can_process_result (SmartPtr<X3aResult> &result)
103 {
104     if (result.ptr() == NULL)
105         return false;
106     switch (result->get_type ()) {
107     case XCAM_3A_RESULT_WHITE_BALANCE:
108     case XCAM_3A_RESULT_BLACK_LEVEL:
109     case XCAM_3A_RESULT_R_GAMMA:
110     case XCAM_3A_RESULT_G_GAMMA:
111     case XCAM_3A_RESULT_B_GAMMA:
112     case XCAM_3A_RESULT_RGB2YUV_MATRIX:
113     case XCAM_3A_RESULT_DEFECT_PIXEL_CORRECTION:
114     case XCAM_3A_RESULT_MACC:
115     case XCAM_3A_RESULT_BAYER_NOISE_REDUCTION:
116     case XCAM_3A_RESULT_BRIGHTNESS:
117     case XCAM_3A_RESULT_3D_NOISE_REDUCTION:
118     case XCAM_3A_RESULT_TEMPORAL_NOISE_REDUCTION_YUV:
119     case XCAM_3A_RESULT_EDGE_ENHANCEMENT:
120         return true;
121 
122     default:
123         return false;
124     }
125 
126     return false;
127 }
128 
129 XCamReturn
apply_3a_results(X3aResultList & results)130 CL3aImageProcessor::apply_3a_results (X3aResultList &results)
131 {
132     XCamReturn ret = XCAM_RETURN_NO_ERROR;
133 
134     for (X3aResultList::iterator iter = results.begin (); iter != results.end (); ++iter)
135     {
136         SmartPtr<X3aResult> &result = *iter;
137         ret = apply_3a_result (result);
138         if (ret != XCAM_RETURN_NO_ERROR)
139             break;
140     }
141     return ret;
142 }
143 
144 XCamReturn
apply_3a_result(SmartPtr<X3aResult> & result)145 CL3aImageProcessor::apply_3a_result (SmartPtr<X3aResult> &result)
146 {
147     STREAM_LOCK;
148 
149     if (result.ptr() == NULL)
150         return XCAM_RETURN_BYPASS;
151 
152     uint32_t res_type = result->get_type ();
153 
154     switch (res_type) {
155     case XCAM_3A_RESULT_WHITE_BALANCE: {
156         SmartPtr<X3aWhiteBalanceResult> wb_res = result.dynamic_cast_ptr<X3aWhiteBalanceResult> ();
157         XCAM_ASSERT (wb_res.ptr ());
158         if (_bayer_basic_pipe.ptr ()) {
159             _bayer_basic_pipe->set_wb_config (wb_res->get_standard_result ());
160             _bayer_basic_pipe->set_3a_result (result);
161         }
162         break;
163     }
164 
165     case XCAM_3A_RESULT_BLACK_LEVEL: {
166         SmartPtr<X3aBlackLevelResult> bl_res = result.dynamic_cast_ptr<X3aBlackLevelResult> ();
167         XCAM_ASSERT (bl_res.ptr ());
168         if (_bayer_basic_pipe.ptr ()) {
169             _bayer_basic_pipe->set_blc_config (bl_res->get_standard_result ());
170             _bayer_basic_pipe->set_3a_result (result);
171         }
172         break;
173     }
174 
175     case XCAM_3A_RESULT_DEFECT_PIXEL_CORRECTION: {
176         SmartPtr<X3aDefectPixelResult> def_res = result.dynamic_cast_ptr<X3aDefectPixelResult> ();
177         XCAM_ASSERT (def_res.ptr ());
178         XCAM_UNUSED (def_res);
179         break;
180     }
181 
182     case XCAM_3A_RESULT_RGB2YUV_MATRIX: {
183         SmartPtr<X3aColorMatrixResult> csc_res = result.dynamic_cast_ptr<X3aColorMatrixResult> ();
184         XCAM_ASSERT (csc_res.ptr ());
185         if (_csc.ptr()) {
186             _csc->set_matrix (csc_res->get_standard_result ());
187             _csc->set_3a_result (result);
188         }
189         if (_yuv_pipe.ptr()) {
190             _yuv_pipe->set_rgbtoyuv_matrix (csc_res->get_standard_result ());
191             _yuv_pipe->set_3a_result (result);
192         }
193         break;
194     }
195 
196     case XCAM_3A_RESULT_MACC: {
197         SmartPtr<X3aMaccMatrixResult> macc_res = result.dynamic_cast_ptr<X3aMaccMatrixResult> ();
198         XCAM_ASSERT (macc_res.ptr ());
199         if (_yuv_pipe.ptr()) {
200             _yuv_pipe->set_macc_table (macc_res->get_standard_result ());
201             _yuv_pipe->set_3a_result (result);
202         }
203         break;
204     }
205     case XCAM_3A_RESULT_R_GAMMA:
206     case XCAM_3A_RESULT_B_GAMMA:
207         break;
208 
209     case XCAM_3A_RESULT_G_GAMMA:
210     case XCAM_3A_RESULT_Y_GAMMA: {
211         SmartPtr<X3aGammaTableResult> gamma_res = result.dynamic_cast_ptr<X3aGammaTableResult> ();
212         XCAM_ASSERT (gamma_res.ptr ());
213         if (_bayer_basic_pipe.ptr ()) {
214             _bayer_basic_pipe->set_gamma_table (gamma_res->get_standard_result ());
215             _bayer_basic_pipe->set_3a_result (result);
216         }
217         break;
218     }
219 
220     case XCAM_3A_RESULT_3D_NOISE_REDUCTION: {
221         SmartPtr<X3aTemporalNoiseReduction> nr_res = result.dynamic_cast_ptr<X3aTemporalNoiseReduction> ();
222         XCAM_ASSERT (nr_res.ptr ());
223         XCAM_UNUSED (nr_res);
224 
225         break;
226     }
227 
228     case XCAM_3A_RESULT_TEMPORAL_NOISE_REDUCTION_YUV: {
229         SmartPtr<X3aTemporalNoiseReduction> tnr_res = result.dynamic_cast_ptr<X3aTemporalNoiseReduction> ();
230         XCAM_ASSERT (tnr_res.ptr ());
231         if (_yuv_pipe.ptr ()) {
232             _yuv_pipe->set_tnr_yuv_config(tnr_res->get_standard_result ());
233             _yuv_pipe->set_3a_result (result);
234         }
235         break;
236     }
237 
238     case XCAM_3A_RESULT_EDGE_ENHANCEMENT: {
239         SmartPtr<X3aEdgeEnhancementResult> ee_ee_res = result.dynamic_cast_ptr<X3aEdgeEnhancementResult> ();
240         XCAM_ASSERT (ee_ee_res.ptr ());
241         if (_bayer_pipe.ptr()) {
242             _bayer_pipe->set_ee_config (ee_ee_res->get_standard_result ());
243             _bayer_pipe->set_3a_result (result);
244         }
245 #if ENABLE_YEENR_HANDLER
246         if (_ee.ptr()) {
247             _ee->set_ee_config_ee (ee_ee_res->get_standard_result ());
248             _ee->set_3a_result (result);
249         }
250 #endif
251         break;
252     }
253 
254     case XCAM_3A_RESULT_BAYER_NOISE_REDUCTION: {
255         SmartPtr<X3aBayerNoiseReduction> bnr_res = result.dynamic_cast_ptr<X3aBayerNoiseReduction> ();
256         XCAM_ASSERT (bnr_res.ptr ());
257         if (_bayer_pipe.ptr()) {
258             _bayer_pipe->set_bnr_config (bnr_res->get_standard_result ());
259             _bayer_pipe->set_3a_result (result);
260         }
261 
262         break;
263     }
264 
265     case XCAM_3A_RESULT_BRIGHTNESS: {
266         SmartPtr<X3aBrightnessResult> brightness_res = result.dynamic_cast_ptr<X3aBrightnessResult> ();
267         XCAM_ASSERT (brightness_res.ptr ());
268         float brightness_level = ((XCam3aResultBrightness)brightness_res->get_standard_result()).brightness_level;
269         XCAM_UNUSED (brightness_level);
270         break;
271     }
272 
273     default:
274         XCAM_LOG_WARNING ("CL3aImageProcessor unknown 3a result:%d", res_type);
275         break;
276     }
277 
278     return XCAM_RETURN_NO_ERROR;
279 }
280 
281 XCamReturn
create_handlers()282 CL3aImageProcessor::create_handlers ()
283 {
284     SmartPtr<CLImageHandler> image_handler;
285     SmartPtr<CLContext> context = get_cl_context ();
286 
287     XCAM_ASSERT (context.ptr ());
288 
289     /* bayer pipeline */
290     image_handler = create_cl_bayer_basic_image_handler (context, _enable_gamma, _3a_stats_bits);
291     _bayer_basic_pipe = image_handler.dynamic_cast_ptr<CLBayerBasicImageHandler> ();
292     XCAM_FAIL_RETURN (
293         WARNING,
294         _bayer_basic_pipe.ptr (),
295         XCAM_RETURN_ERROR_CL,
296         "CL3aImageProcessor create bayer basic pipe handler failed");
297     image_handler->set_pool_size (XCAM_CL_3A_IMAGE_MAX_POOL_SIZE);
298     _bayer_basic_pipe->set_stats_callback (_stats_callback);
299     add_handler (image_handler);
300 
301     /* tone mapping */
302     switch(_wdr_mode) {
303     case Gaussian: {
304         image_handler = create_cl_tonemapping_image_handler (context);
305         _tonemapping = image_handler.dynamic_cast_ptr<CLTonemappingImageHandler> ();
306         XCAM_FAIL_RETURN (
307             WARNING,
308             _tonemapping.ptr (),
309             XCAM_RETURN_ERROR_CL,
310             "CL3aImageProcessor create tonemapping handler failed");
311         _tonemapping->enable_handler (true);
312         image_handler->set_pool_size (XCAM_CL_3A_IMAGE_MAX_POOL_SIZE);
313         add_handler (image_handler);
314         break;
315     }
316     case Haleq: {
317         image_handler = create_cl_newtonemapping_image_handler (context);
318         _newtonemapping = image_handler.dynamic_cast_ptr<CLNewTonemappingImageHandler> ();
319         XCAM_FAIL_RETURN (
320             WARNING,
321             _newtonemapping.ptr (),
322             XCAM_RETURN_ERROR_CL,
323             "CL3aImageProcessor create tonemapping handler failed");
324         _newtonemapping->enable_handler (true);
325         image_handler->set_pool_size (XCAM_CL_3A_IMAGE_MAX_POOL_SIZE);
326         add_handler (image_handler);
327         break;
328     }
329     default:
330         XCAM_LOG_DEBUG ("WDR disabled");
331         break;
332     }
333 
334     /* bayer pipe */
335     image_handler = create_cl_bayer_pipe_image_handler (context);
336     _bayer_pipe = image_handler.dynamic_cast_ptr<CLBayerPipeImageHandler> ();
337     XCAM_FAIL_RETURN (
338         WARNING,
339         image_handler.ptr (),
340         XCAM_RETURN_ERROR_CL,
341         "CL3aImageProcessor create bayer pipe handler failed");
342 
343     _bayer_pipe->enable_denoise (XCAM_DENOISE_TYPE_BNR & _snr_mode);
344     image_handler->set_pool_size (XCAM_CL_3A_IMAGE_MAX_POOL_SIZE * 2);
345     add_handler (image_handler);
346     if(_capture_stage == BasicbayerStage)
347         return XCAM_RETURN_NO_ERROR;
348 
349     image_handler = create_cl_yuv_pipe_image_handler (context);
350     _yuv_pipe = image_handler.dynamic_cast_ptr<CLYuvPipeImageHandler> ();
351     XCAM_FAIL_RETURN (
352         WARNING,
353         _yuv_pipe.ptr (),
354         XCAM_RETURN_ERROR_CL,
355         "CL3aImageProcessor create yuv pipe handler failed");
356     _yuv_pipe->set_tnr_enable (_tnr_mode & CL_TNR_TYPE_YUV);
357     image_handler->set_pool_size (XCAM_CL_3A_IMAGE_MAX_POOL_SIZE * 2);
358     add_handler (image_handler);
359 
360 #if ENABLE_YEENR_HANDLER
361     /* ee */
362     image_handler = create_cl_ee_image_handler (context);
363     _ee = image_handler.dynamic_cast_ptr<CLEeImageHandler> ();
364     XCAM_FAIL_RETURN (
365         WARNING,
366         _ee.ptr (),
367         XCAM_RETURN_ERROR_CL,
368         "CL3aImageProcessor create ee handler failed");
369     _ee->enable_handler (XCAM_DENOISE_TYPE_EE & _snr_mode);
370     image_handler->set_pool_type (CLImageHandler::CLVideoPoolType);
371     image_handler->set_pool_size (XCAM_CL_3A_IMAGE_MAX_POOL_SIZE);
372     add_handler (image_handler);
373 #endif
374 
375     XCAM_FAIL_RETURN (
376         WARNING,
377         post_config (),
378         XCAM_RETURN_ERROR_CL,
379         "CL3aImageProcessor post_config failed");
380 
381     return XCAM_RETURN_NO_ERROR;
382 }
383 
384 bool
post_config()385 CL3aImageProcessor::post_config ()
386 {
387     CLImageProcessor::ImageHandlerList::iterator i_handler = handlers_begin ();
388     CLImageProcessor::ImageHandlerList::iterator end = handlers_end ();
389     uint32_t swap_y_count = 0;
390     bool start_count = false;
391     bool ret = true;
392 
393     if (!_yuv_pipe.ptr ())  //not necessary to check
394         return true;
395 
396     for (; i_handler != end; ++i_handler) {
397         if (!start_count) {
398             SmartPtr<CLYuvPipeImageHandler> convert_yuv = (*i_handler).dynamic_cast_ptr<CLYuvPipeImageHandler> ();
399             if (convert_yuv.ptr () && convert_yuv.ptr () == _yuv_pipe.ptr ())
400                 start_count = true;
401             continue;
402         }
403 
404         SmartPtr<CLCloneImageHandler> clone_y = (*i_handler).dynamic_cast_ptr<CLCloneImageHandler> ();
405         if (clone_y.ptr () && clone_y->is_handler_enabled () && (clone_y->get_clone_flags () & SwappedBuffer::SwapY))
406             swap_y_count++;
407     }
408 
409     if (swap_y_count % 2 == 1)
410         ret = _yuv_pipe->enable_buf_pool_swap_flags (SwappedBuffer::SwapY | SwappedBuffer::SwapUV, SwappedBuffer::OrderY1Y0 | SwappedBuffer::OrderUV0UV1);
411     else
412         ret = _yuv_pipe->enable_buf_pool_swap_flags (SwappedBuffer::SwapY | SwappedBuffer::SwapUV, SwappedBuffer::OrderY0Y1 | SwappedBuffer::OrderUV0UV1);
413 
414     return ret;
415 }
416 
417 bool
set_profile(const CL3aImageProcessor::PipelineProfile value)418 CL3aImageProcessor::set_profile (const CL3aImageProcessor::PipelineProfile value)
419 {
420     _pipeline_profile = value;
421 
422     if (value >= AdvancedPipelineProfile)
423         _tnr_mode |= CL_TNR_TYPE_YUV;
424 
425     if (value >= ExtremePipelineProfile) {
426         _snr_mode |= XCAM_DENOISE_TYPE_BNR;
427     }
428     STREAM_LOCK;
429     if (_yuv_pipe.ptr ())
430         _yuv_pipe->set_tnr_enable (_tnr_mode & CL_TNR_TYPE_YUV);
431 
432     return true;
433 }
434 
435 bool
set_gamma(bool enable)436 CL3aImageProcessor::set_gamma (bool enable)
437 {
438     _enable_gamma = enable;
439 
440     STREAM_LOCK;
441 
442     return true;
443 }
444 
445 bool
set_denoise(uint32_t mode)446 CL3aImageProcessor::set_denoise (uint32_t mode)
447 {
448     _snr_mode = mode;
449 
450     STREAM_LOCK;
451     if (_bayer_pipe.ptr ())
452         _bayer_pipe->enable_denoise (XCAM_DENOISE_TYPE_BNR & _snr_mode);
453 
454     return true;
455 }
456 
457 bool
set_macc(bool enable)458 CL3aImageProcessor::set_macc (bool enable)
459 {
460     _enable_macc = enable;
461 
462     STREAM_LOCK;
463     return true;
464 }
465 
466 bool
set_tonemapping(CLTonemappingMode wdr_mode)467 CL3aImageProcessor::set_tonemapping (CLTonemappingMode wdr_mode)
468 {
469     _wdr_mode = wdr_mode;
470 
471     STREAM_LOCK;
472 
473     return true;
474 }
475 
476 bool
set_tnr(uint32_t mode,uint8_t level)477 CL3aImageProcessor::set_tnr (uint32_t mode, uint8_t level)
478 {
479     XCAM_UNUSED (level);
480     _tnr_mode = mode;
481 
482     STREAM_LOCK;
483     if (_yuv_pipe.ptr ())
484         _yuv_pipe->set_tnr_enable (_tnr_mode & CL_TNR_TYPE_YUV);
485 
486     return true;
487 }
488 
489 };
490