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>
19 * Wind Yuan <feng.yuan@intel.com>
20 */
21
22 #include "smart_analysis_handler.h"
23 #include "smart_analyzer_loader.h"
24 #include "smart_analyzer.h"
25 #include "video_buffer.h"
26
27 namespace XCam {
28
29 SmartAnalysisHandler::SmartHandlerMap SmartAnalysisHandler::_handler_map;
30 Mutex SmartAnalysisHandler::_handler_map_lock;
31
SmartAnalysisHandler(XCamSmartAnalysisDescription * desc,SmartPtr<SmartAnalyzerLoader> & loader,const char * name)32 SmartAnalysisHandler::SmartAnalysisHandler (XCamSmartAnalysisDescription *desc, SmartPtr<SmartAnalyzerLoader> &loader, const char *name)
33 : _desc (desc)
34 , _loader (loader)
35 , _analyzer (NULL)
36 , _name (NULL)
37 , _context (NULL)
38 , _async_mode (false)
39 {
40 if (name)
41 _name = strndup (name, XCAM_MAX_STR_SIZE);
42 }
43
~SmartAnalysisHandler()44 SmartAnalysisHandler::~SmartAnalysisHandler ()
45 {
46 if (is_valid ())
47 destroy_context ();
48
49 if (_name)
50 xcam_free (_name);
51 }
52
53 XCamReturn
create_context(SmartPtr<SmartAnalysisHandler> & self)54 SmartAnalysisHandler::create_context (SmartPtr<SmartAnalysisHandler> &self)
55 {
56 XCamSmartAnalysisContext *context = NULL;
57 XCamReturn ret = XCAM_RETURN_NO_ERROR;
58 uint32_t async_mode = 0;
59 XCAM_ASSERT (!_context);
60 XCAM_ASSERT (self.ptr () == this);
61 if ((ret = _desc->create_context (&context, &async_mode, NULL)) != XCAM_RETURN_NO_ERROR) {
62 XCAM_LOG_WARNING ("smart handler(%s) lib create context failed", XCAM_STR(get_name()));
63 return ret;
64 }
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;
75 _context = context;
76 return XCAM_RETURN_NO_ERROR;
77 }
78
79 void
destroy_context()80 SmartAnalysisHandler::destroy_context ()
81 {
82 XCamSmartAnalysisContext *context;
83 {
84 SmartLock locker (_handler_map_lock);
85 context = _context;
86 _context = NULL;
87 if (context)
88 _handler_map.erase (context);
89 }
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
post_aync_results(XCamSmartAnalysisContext * context,const XCamVideoBuffer * buffer,XCam3aResultHead * results[],uint32_t res_count)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
112 if (!handler.ptr ()) {
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
post_smart_results(const XCamVideoBuffer * buffer,XCam3aResultHead * results[],uint32_t res_count)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)
132 _analyzer->post_smart_results (result_list, (buffer ? buffer->timestamp : InvalidTimestamp));
133
134 return XCAM_RETURN_NO_ERROR;
135 }
136
137 XCamReturn
update_params(XCamSmartAnalysisParam & params)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
analyze(const SmartPtr<VideoBuffer> & buffer,X3aResultList & results)153 SmartAnalysisHandler::analyze (const SmartPtr<VideoBuffer> &buffer, X3aResultList &results)
154 {
155 XCAM_LOG_DEBUG ("smart handler(%s) analyze", XCAM_STR(get_name()));
156 XCamReturn ret = XCAM_RETURN_NO_ERROR;
157 XCamVideoBuffer *video_buffer = convert_to_external_buffer (buffer);
158 XCam3aResultHead *res_array[XCAM_3A_MAX_RESULT_COUNT];
159 uint32_t res_count = XCAM_3A_MAX_RESULT_COUNT;
160
161 XCAM_ASSERT (buffer.ptr ());
162 XCAM_ASSERT (_context);
163 XCAM_ASSERT (video_buffer);
164 xcam_mem_clear (res_array);
165
166 ret = _desc->analyze (_context, video_buffer, res_array, &res_count);
167 XCAM_ASSERT (video_buffer->unref);
168 video_buffer->unref (video_buffer);
169 XCAM_FAIL_RETURN (WARNING,
170 ret == XCAM_RETURN_NO_ERROR,
171 ret,
172 "smart handler(%s) calculation failed", XCAM_STR(get_name()));
173
174 if (res_count > 0 && res_array[0]) {
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()));
180 _desc->free_results (_context, res_array, res_count);
181 }
182
183 return ret;
184 }
185
186 XCamReturn
convert_results(XCam3aResultHead * from[],uint32_t from_count,X3aResultList & to)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 }
199