| /* |
| * smart_analysis_handler.cpp - smart analysis handler |
| * |
| * Copyright (c) 2015 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 <[email protected]> |
| * Wind Yuan <[email protected]> |
| */ |
| |
| #include "smart_analysis_handler.h" |
| #include "smart_analyzer_loader.h" |
| #include "smart_analyzer.h" |
| #include "video_buffer.h" |
| |
| namespace XCam { |
| |
| SmartAnalysisHandler::SmartHandlerMap SmartAnalysisHandler::_handler_map; |
| Mutex SmartAnalysisHandler::_handler_map_lock; |
| |
| SmartAnalysisHandler::SmartAnalysisHandler (XCamSmartAnalysisDescription *desc, SmartPtr<SmartAnalyzerLoader> &loader, const char *name) |
| : _desc (desc) |
| , _loader (loader) |
| , _analyzer (NULL) |
| , _name (NULL) |
| , _context (NULL) |
| , _async_mode (false) |
| { |
| if (name) |
| _name = strndup (name, XCAM_MAX_STR_SIZE); |
| } |
| |
| SmartAnalysisHandler::~SmartAnalysisHandler () |
| { |
| if (is_valid ()) |
| destroy_context (); |
| |
| if (_name) |
| xcam_free (_name); |
| } |
| |
| XCamReturn |
| SmartAnalysisHandler::create_context (SmartPtr<SmartAnalysisHandler> &self) |
| { |
| XCamSmartAnalysisContext *context = NULL; |
| XCamReturn ret = XCAM_RETURN_NO_ERROR; |
| uint32_t async_mode = 0; |
| XCAM_ASSERT (!_context); |
| XCAM_ASSERT (self.ptr () == this); |
| if ((ret = _desc->create_context (&context, &async_mode, NULL)) != XCAM_RETURN_NO_ERROR) { |
| XCAM_LOG_WARNING ("smart handler(%s) lib create context failed", XCAM_STR(get_name())); |
| return ret; |
| } |
| if (!context) { |
| XCAM_LOG_WARNING ("smart handler(%s) lib create context failed with NULL context", XCAM_STR(get_name())); |
| return XCAM_RETURN_ERROR_UNKNOWN; |
| } |
| _async_mode = async_mode; |
| |
| XCAM_LOG_INFO ("create smart analysis context(%s)", XCAM_STR(get_name())); |
| |
| SmartLock locker (_handler_map_lock); |
| _handler_map[context] = self; |
| _context = context; |
| return XCAM_RETURN_NO_ERROR; |
| } |
| |
| void |
| SmartAnalysisHandler::destroy_context () |
| { |
| XCamSmartAnalysisContext *context; |
| { |
| SmartLock locker (_handler_map_lock); |
| context = _context; |
| _context = NULL; |
| if (context) |
| _handler_map.erase (context); |
| } |
| |
| if (context && _desc && _desc->destroy_context) { |
| _desc->destroy_context (context); |
| XCAM_LOG_INFO ("destroy smart analysis context(%s)", XCAM_STR(get_name())); |
| } |
| } |
| |
| XCamReturn |
| SmartAnalysisHandler::post_aync_results ( |
| XCamSmartAnalysisContext *context, |
| const XCamVideoBuffer *buffer, |
| XCam3aResultHead *results[], uint32_t res_count) |
| { |
| SmartPtr<SmartAnalysisHandler> handler = NULL; |
| XCAM_ASSERT (context); |
| { |
| SmartLock locker (_handler_map_lock); |
| SmartHandlerMap::iterator i_h = _handler_map.find (context); |
| if (i_h != _handler_map.end ()) |
| handler = i_h->second; |
| } |
| |
| if (!handler.ptr ()) { |
| XCAM_LOG_WARNING ("can't find a proper smart analyzer handler, please check context pointer"); |
| return XCAM_RETURN_ERROR_PARAM; |
| } |
| |
| return handler->post_smart_results (buffer, results, res_count); |
| } |
| |
| XCamReturn |
| SmartAnalysisHandler::post_smart_results (const XCamVideoBuffer *buffer, XCam3aResultHead *results[], uint32_t res_count) |
| { |
| X3aResultList result_list; |
| XCamReturn ret = convert_results (results, res_count, result_list); |
| XCAM_FAIL_RETURN ( |
| WARNING, |
| ret == XCAM_RETURN_NO_ERROR, |
| ret, |
| "smart handler convert results failed in async mode"); |
| |
| if (_analyzer) |
| _analyzer->post_smart_results (result_list, (buffer ? buffer->timestamp : InvalidTimestamp)); |
| |
| return XCAM_RETURN_NO_ERROR; |
| } |
| |
| XCamReturn |
| SmartAnalysisHandler::update_params (XCamSmartAnalysisParam ¶ms) |
| { |
| XCamReturn ret = XCAM_RETURN_NO_ERROR; |
| |
| XCAM_ASSERT (_context); |
| ret = _desc->update_params (_context, ¶ms); |
| XCAM_FAIL_RETURN (WARNING, |
| ret == XCAM_RETURN_NO_ERROR, |
| ret, |
| "smart handler(%s) update parameters failed", XCAM_STR(get_name())); |
| |
| return ret; |
| } |
| |
| XCamReturn |
| SmartAnalysisHandler::analyze (const SmartPtr<VideoBuffer> &buffer, X3aResultList &results) |
| { |
| XCAM_LOG_DEBUG ("smart handler(%s) analyze", XCAM_STR(get_name())); |
| XCamReturn ret = XCAM_RETURN_NO_ERROR; |
| XCamVideoBuffer *video_buffer = convert_to_external_buffer (buffer); |
| XCam3aResultHead *res_array[XCAM_3A_MAX_RESULT_COUNT]; |
| uint32_t res_count = XCAM_3A_MAX_RESULT_COUNT; |
| |
| XCAM_ASSERT (buffer.ptr ()); |
| XCAM_ASSERT (_context); |
| XCAM_ASSERT (video_buffer); |
| xcam_mem_clear (res_array); |
| |
| ret = _desc->analyze (_context, video_buffer, res_array, &res_count); |
| XCAM_ASSERT (video_buffer->unref); |
| video_buffer->unref (video_buffer); |
| XCAM_FAIL_RETURN (WARNING, |
| ret == XCAM_RETURN_NO_ERROR, |
| ret, |
| "smart handler(%s) calculation failed", XCAM_STR(get_name())); |
| |
| if (res_count > 0 && res_array[0]) { |
| ret = convert_results (res_array, res_count, results); |
| XCAM_FAIL_RETURN (WARNING, |
| ret == XCAM_RETURN_NO_ERROR, |
| ret, |
| "smart handler(%s) convert_results failed", XCAM_STR(get_name())); |
| _desc->free_results (_context, res_array, res_count); |
| } |
| |
| return ret; |
| } |
| |
| XCamReturn |
| SmartAnalysisHandler::convert_results (XCam3aResultHead *from[], uint32_t from_count, X3aResultList &to) |
| { |
| for (uint32_t i = 0; i < from_count; ++i) { |
| SmartPtr<X3aResult> standard_res = |
| X3aResultFactory::instance ()->create_3a_result (from[i]); |
| to.push_back (standard_res); |
| } |
| |
| return XCAM_RETURN_NO_ERROR; |
| } |
| |
| } |