zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 1 | /* |
| 2 | * smart_analysis_handler.cpp - smart analysis handler |
| 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: Zong Wei <wei.zong@intel.com> |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 19 | * Wind Yuan <feng.yuan@intel.com> |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 20 | */ |
| 21 | |
| 22 | #include "smart_analysis_handler.h" |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 23 | #include "smart_analyzer_loader.h" |
| 24 | #include "smart_analyzer.h" |
Wind Yuan | 6d144ce | 2017-08-16 18:29:29 +0800 | [diff] [blame] | 25 | #include "video_buffer.h" |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 26 | |
| 27 | namespace XCam { |
| 28 | |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 29 | SmartAnalysisHandler::SmartHandlerMap SmartAnalysisHandler::_handler_map; |
| 30 | Mutex SmartAnalysisHandler::_handler_map_lock; |
| 31 | |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 32 | SmartAnalysisHandler::SmartAnalysisHandler (XCamSmartAnalysisDescription *desc, SmartPtr<SmartAnalyzerLoader> &loader, const char *name) |
| 33 | : _desc (desc) |
| 34 | , _loader (loader) |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 35 | , _analyzer (NULL) |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 36 | , _name (NULL) |
| 37 | , _context (NULL) |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 38 | , _async_mode (false) |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 39 | { |
| 40 | if (name) |
Wind Yuan | 155c8f5 | 2016-03-18 23:16:59 +0800 | [diff] [blame] | 41 | _name = strndup (name, XCAM_MAX_STR_SIZE); |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 42 | } |
| 43 | |
| 44 | SmartAnalysisHandler::~SmartAnalysisHandler () |
| 45 | { |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 46 | if (is_valid ()) |
| 47 | destroy_context (); |
| 48 | |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 49 | if (_name) |
| 50 | xcam_free (_name); |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 51 | } |
| 52 | |
| 53 | XCamReturn |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 54 | SmartAnalysisHandler::create_context (SmartPtr<SmartAnalysisHandler> &self) |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 55 | { |
| 56 | XCamSmartAnalysisContext *context = NULL; |
| 57 | XCamReturn ret = XCAM_RETURN_NO_ERROR; |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 58 | uint32_t async_mode = 0; |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 59 | XCAM_ASSERT (!_context); |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 60 | XCAM_ASSERT (self.ptr () == this); |
| 61 | if ((ret = _desc->create_context (&context, &async_mode, NULL)) != XCAM_RETURN_NO_ERROR) { |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 62 | XCAM_LOG_WARNING ("smart handler(%s) lib create context failed", XCAM_STR(get_name())); |
| 63 | return ret; |
| 64 | } |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 65 | if (!context) { |
| 66 | XCAM_LOG_WARNING ("smart handler(%s) lib create context failed with NULL context", XCAM_STR(get_name())); |
| 67 | return XCAM_RETURN_ERROR_UNKNOWN; |
| 68 | } |
| 69 | _async_mode = async_mode; |
| 70 | |
| 71 | XCAM_LOG_INFO ("create smart analysis context(%s)", XCAM_STR(get_name())); |
| 72 | |
| 73 | SmartLock locker (_handler_map_lock); |
| 74 | _handler_map[context] = self; |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 75 | _context = context; |
| 76 | return XCAM_RETURN_NO_ERROR; |
| 77 | } |
| 78 | |
| 79 | void |
| 80 | SmartAnalysisHandler::destroy_context () |
| 81 | { |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 82 | XCamSmartAnalysisContext *context; |
| 83 | { |
| 84 | SmartLock locker (_handler_map_lock); |
| 85 | context = _context; |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 86 | _context = NULL; |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 87 | if (context) |
| 88 | _handler_map.erase (context); |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 89 | } |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 90 | |
| 91 | if (context && _desc && _desc->destroy_context) { |
| 92 | _desc->destroy_context (context); |
| 93 | XCAM_LOG_INFO ("destroy smart analysis context(%s)", XCAM_STR(get_name())); |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | XCamReturn |
| 98 | SmartAnalysisHandler::post_aync_results ( |
| 99 | XCamSmartAnalysisContext *context, |
| 100 | const XCamVideoBuffer *buffer, |
| 101 | XCam3aResultHead *results[], uint32_t res_count) |
| 102 | { |
| 103 | SmartPtr<SmartAnalysisHandler> handler = NULL; |
| 104 | XCAM_ASSERT (context); |
| 105 | { |
| 106 | SmartLock locker (_handler_map_lock); |
| 107 | SmartHandlerMap::iterator i_h = _handler_map.find (context); |
| 108 | if (i_h != _handler_map.end ()) |
| 109 | handler = i_h->second; |
| 110 | } |
| 111 | |
Yinhang Liu | 1aa9760 | 2016-05-27 14:58:21 +0800 | [diff] [blame] | 112 | if (!handler.ptr ()) { |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 113 | XCAM_LOG_WARNING ("can't find a proper smart analyzer handler, please check context pointer"); |
| 114 | return XCAM_RETURN_ERROR_PARAM; |
| 115 | } |
| 116 | |
| 117 | return handler->post_smart_results (buffer, results, res_count); |
| 118 | } |
| 119 | |
| 120 | XCamReturn |
| 121 | SmartAnalysisHandler::post_smart_results (const XCamVideoBuffer *buffer, XCam3aResultHead *results[], uint32_t res_count) |
| 122 | { |
| 123 | X3aResultList result_list; |
| 124 | XCamReturn ret = convert_results (results, res_count, result_list); |
| 125 | XCAM_FAIL_RETURN ( |
| 126 | WARNING, |
| 127 | ret == XCAM_RETURN_NO_ERROR, |
| 128 | ret, |
| 129 | "smart handler convert results failed in async mode"); |
| 130 | |
| 131 | if (_analyzer) |
Yinhang Liu | 1aa9760 | 2016-05-27 14:58:21 +0800 | [diff] [blame] | 132 | _analyzer->post_smart_results (result_list, (buffer ? buffer->timestamp : InvalidTimestamp)); |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 133 | |
| 134 | return XCAM_RETURN_NO_ERROR; |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 135 | } |
| 136 | |
| 137 | XCamReturn |
| 138 | SmartAnalysisHandler::update_params (XCamSmartAnalysisParam ¶ms) |
| 139 | { |
| 140 | XCamReturn ret = XCAM_RETURN_NO_ERROR; |
| 141 | |
| 142 | XCAM_ASSERT (_context); |
| 143 | ret = _desc->update_params (_context, ¶ms); |
| 144 | XCAM_FAIL_RETURN (WARNING, |
| 145 | ret == XCAM_RETURN_NO_ERROR, |
| 146 | ret, |
| 147 | "smart handler(%s) update parameters failed", XCAM_STR(get_name())); |
| 148 | |
| 149 | return ret; |
| 150 | } |
| 151 | |
| 152 | XCamReturn |
Wind Yuan | 6d144ce | 2017-08-16 18:29:29 +0800 | [diff] [blame] | 153 | SmartAnalysisHandler::analyze (const SmartPtr<VideoBuffer> &buffer, X3aResultList &results) |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 154 | { |
| 155 | XCAM_LOG_DEBUG ("smart handler(%s) analyze", XCAM_STR(get_name())); |
| 156 | XCamReturn ret = XCAM_RETURN_NO_ERROR; |
Wind Yuan | 226b6af | 2017-03-07 05:16:31 -0500 | [diff] [blame] | 157 | XCamVideoBuffer *video_buffer = convert_to_external_buffer (buffer); |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 158 | XCam3aResultHead *res_array[XCAM_3A_MAX_RESULT_COUNT]; |
| 159 | uint32_t res_count = XCAM_3A_MAX_RESULT_COUNT; |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 160 | |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 161 | XCAM_ASSERT (buffer.ptr ()); |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 162 | XCAM_ASSERT (_context); |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 163 | XCAM_ASSERT (video_buffer); |
| 164 | xcam_mem_clear (res_array); |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 165 | |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 166 | ret = _desc->analyze (_context, video_buffer, res_array, &res_count); |
| 167 | XCAM_ASSERT (video_buffer->unref); |
| 168 | video_buffer->unref (video_buffer); |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 169 | XCAM_FAIL_RETURN (WARNING, |
| 170 | ret == XCAM_RETURN_NO_ERROR, |
| 171 | ret, |
| 172 | "smart handler(%s) calculation failed", XCAM_STR(get_name())); |
| 173 | |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 174 | if (res_count > 0 && res_array[0]) { |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 175 | ret = convert_results (res_array, res_count, results); |
| 176 | XCAM_FAIL_RETURN (WARNING, |
| 177 | ret == XCAM_RETURN_NO_ERROR, |
| 178 | ret, |
| 179 | "smart handler(%s) convert_results failed", XCAM_STR(get_name())); |
Wind Yuan | 7f8d9e0 | 2016-03-30 22:49:57 +0800 | [diff] [blame] | 180 | _desc->free_results (_context, res_array, res_count); |
zongwave | 03954a3 | 2015-09-22 15:40:44 +0800 | [diff] [blame] | 181 | } |
| 182 | |
| 183 | return ret; |
| 184 | } |
| 185 | |
| 186 | XCamReturn |
| 187 | SmartAnalysisHandler::convert_results (XCam3aResultHead *from[], uint32_t from_count, X3aResultList &to) |
| 188 | { |
| 189 | for (uint32_t i = 0; i < from_count; ++i) { |
| 190 | SmartPtr<X3aResult> standard_res = |
| 191 | X3aResultFactory::instance ()->create_3a_result (from[i]); |
| 192 | to.push_back (standard_res); |
| 193 | } |
| 194 | |
| 195 | return XCAM_RETURN_NO_ERROR; |
| 196 | } |
| 197 | |
| 198 | } |