/*
|
* 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 <wei.zong@intel.com>
|
* Wind Yuan <feng.yuan@intel.com>
|
*/
|
|
#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;
|
}
|
|
}
|