| /* |
| * Copyright (C) 2015, Samsung Electronics Co. LTD |
| * |
| * 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. |
| */ |
| |
| #define LOG_TAG "ExynosVisionReference" |
| #include <cutils/log.h> |
| |
| #include "ExynosVisionReference.h" |
| #include "ExynosVisionContext.h" |
| #include "ExynosVisionGraph.h" |
| #include "ExynosVisionSubgraph.h" |
| #include "ExynosVisionNode.h" |
| #include "ExynosVisionImage.h" |
| #include "ExynosVisionArray.h" |
| #include "ExynosVisionDistribution.h" |
| #include "ExynosVisionThreshold.h" |
| #include "ExynosVisionLut.h" |
| #include "ExynosVisionConvolution.h" |
| #include "ExynosVisionDelay.h" |
| #include "ExynosVisionRemap.h" |
| #include "ExynosVisionPyramid.h" |
| #include "ExynosVisionMatrix.h" |
| |
| namespace android { |
| |
| Mutex ExynosVisionReference::m_global_lock; |
| vx_uint32 ExynosVisionReference::m_ref_id_cnt = 0; |
| |
| typedef struct _vx_type_size { |
| vx_enum type; |
| vx_size size; |
| } vx_type_size_t; |
| |
| static vx_type_size_t type_sizes[] = { |
| {VX_TYPE_INVALID, 0}, |
| // scalars |
| {VX_TYPE_CHAR, sizeof(vx_char)}, |
| {VX_TYPE_INT8, sizeof(vx_int8)}, |
| {VX_TYPE_INT16, sizeof(vx_int16)}, |
| {VX_TYPE_INT32, sizeof(vx_int32)}, |
| {VX_TYPE_INT64, sizeof(vx_int64)}, |
| {VX_TYPE_UINT8, sizeof(vx_uint8)}, |
| {VX_TYPE_UINT16, sizeof(vx_uint16)}, |
| {VX_TYPE_UINT32, sizeof(vx_uint32)}, |
| {VX_TYPE_UINT64, sizeof(vx_uint64)}, |
| {VX_TYPE_FLOAT32, sizeof(vx_float32)}, |
| {VX_TYPE_FLOAT64, sizeof(vx_float64)}, |
| {VX_TYPE_ENUM, sizeof(vx_enum)}, |
| {VX_TYPE_BOOL, sizeof(vx_bool)}, |
| {VX_TYPE_SIZE, sizeof(vx_size)}, |
| {VX_TYPE_DF_IMAGE, sizeof(vx_df_image)}, |
| // structures |
| {VX_TYPE_RECTANGLE, sizeof(vx_rectangle_t)}, |
| {VX_TYPE_COORDINATES2D, sizeof(vx_coordinates2d_t)}, |
| {VX_TYPE_COORDINATES3D, sizeof(vx_coordinates3d_t)}, |
| {VX_TYPE_KEYPOINT, sizeof(vx_keypoint_t)}, |
| // pseudo objects |
| {VX_TYPE_ERROR, sizeof(ExynosVisionError)}, |
| {VX_TYPE_META_FORMAT,sizeof(ExynosVisionMeta)}, |
| // framework objects |
| {VX_TYPE_REFERENCE, sizeof(ExynosVisionReference)}, |
| {VX_TYPE_CONTEXT, sizeof(ExynosVisionContext)}, |
| {VX_TYPE_GRAPH, sizeof(ExynosVisionGraph)}, |
| {VX_TYPE_NODE, sizeof(ExynosVisionNode)}, |
| {VX_TYPE_TARGET, sizeof(ExynosVisionTarget)}, |
| {VX_TYPE_PARAMETER, sizeof(ExynosVisionParameter)}, |
| {VX_TYPE_KERNEL, sizeof(ExynosVisionKernel)}, |
| // data objects |
| {VX_TYPE_ARRAY, sizeof(ExynosVisionArray)}, |
| {VX_TYPE_CONVOLUTION, sizeof(ExynosVisionConvolution)}, |
| {VX_TYPE_DELAY, sizeof(ExynosVisionDelay)}, |
| {VX_TYPE_DISTRIBUTION, sizeof(ExynosVisionDistribution)}, |
| {VX_TYPE_IMAGE, sizeof(ExynosVisionImage)}, |
| {VX_TYPE_LUT, sizeof(ExynosVisionLut)}, |
| {VX_TYPE_MATRIX, sizeof(ExynosVisionMatrix)}, |
| {VX_TYPE_PYRAMID, sizeof(ExynosVisionPyramid)}, |
| {VX_TYPE_REMAP, sizeof(ExynosVisionRemap)}, |
| {VX_TYPE_SCALAR, sizeof(ExynosVisionScalar)}, |
| {VX_TYPE_THRESHOLD, sizeof(ExynosVisionThreshold)}, |
| // others |
| }; |
| |
| static vx_bool getTypeName(vx_enum type, vx_char *name) |
| { |
| vx_bool ret = vx_true_e; |
| |
| switch(type) { |
| case VX_TYPE_ERROR: |
| strcpy(name, "ERROR"); |
| break; |
| case VX_TYPE_META_FORMAT: |
| strcpy(name, "META"); |
| break; |
| case VX_TYPE_REFERENCE: |
| strcpy(name, "REFERENCE"); |
| break; |
| case VX_TYPE_CONTEXT: |
| strcpy(name, "CONTEXT"); |
| break; |
| case VX_TYPE_GRAPH: |
| strcpy(name, "GRAPH"); |
| break; |
| case VX_TYPE_NODE: |
| strcpy(name, "NODE"); |
| break; |
| case VX_TYPE_PARAMETER: |
| strcpy(name, "PARAMETER"); |
| break; |
| case VX_TYPE_TARGET: |
| strcpy(name, "TARGET"); |
| break; |
| case VX_TYPE_KERNEL: |
| strcpy(name, "KERNEL"); |
| break; |
| case VX_TYPE_ARRAY: |
| strcpy(name, "ARRAY"); |
| break; |
| case VX_TYPE_CONVOLUTION: |
| strcpy(name, "CONVOLUTION"); |
| break; |
| case VX_TYPE_DELAY: |
| strcpy(name, "DELAY"); |
| break; |
| case VX_TYPE_DISTRIBUTION: |
| strcpy(name, "DISTRIBUTION"); |
| break; |
| case VX_TYPE_IMAGE: |
| strcpy(name, "IMAGE"); |
| break; |
| case VX_TYPE_LUT: |
| strcpy(name, "LUT"); |
| break; |
| case VX_TYPE_MATRIX: |
| strcpy(name, "MATRIX"); |
| break; |
| case VX_TYPE_PYRAMID: |
| strcpy(name, "PYRAMID"); |
| break; |
| case VX_TYPE_REMAP: |
| strcpy(name, "REMAP"); |
| break; |
| case VX_TYPE_SCALAR: |
| strcpy(name, "SCALAR"); |
| break; |
| case VX_TYPE_THRESHOLD: |
| strcpy(name, "THRESHOLD"); |
| break; |
| default: |
| VXLOGE("no type, 0x%X", type); |
| strcpy(name, "UNKNOWN"); |
| ret = vx_false_e; |
| break; |
| } |
| |
| return ret; |
| } |
| |
| vx_bool |
| ExynosVisionReference::isValidReference(ExynosVisionReference *ref) |
| { |
| vx_bool ret = vx_false_e; |
| |
| if (ref != NULL) { |
| if ((ref->m_magic == VX_MAGIC) && |
| ((vxIsValidType(ref->getType())) && ref->getType() != VX_TYPE_CONTEXT) && |
| (ExynosVisionContext::isValidContext(ref->getContext()) == vx_true_e)) { |
| ret = vx_true_e; |
| } |
| } else { |
| VXLOGE("reference was NULL"); |
| } |
| |
| return ret; |
| } |
| |
| vx_bool |
| ExynosVisionReference::isValidReference(ExynosVisionReference *ref, vx_enum type) |
| { |
| vx_bool ret = vx_false_e; |
| if (ref != NULL) { |
| if ((ref->m_magic == VX_MAGIC) && |
| ((ref->getType() == type) && (ref->getType() != VX_TYPE_CONTEXT)) && |
| (ExynosVisionContext::isValidContext(ref->getContext()) == vx_true_e)) { |
| ret = vx_true_e; |
| } else { |
| VXLOGE("ref(%p) is not a valid reference, expected type:%p", ref, type); |
| ref->displayInfo(0, vx_true_e); |
| } |
| } else { |
| VXLOGE("reference was NULL"); |
| } |
| return ret; |
| } |
| |
| vx_status |
| ExynosVisionReference::releaseReferenceInt(ExynosVisionReference **ref, vx_enum reftype, ExynosVisionReference *releasing_ref) |
| { |
| vx_status status = VX_SUCCESS; |
| |
| if ((*ref)->decrementReference(reftype, releasing_ref) == 0) { |
| status = (*ref)->getContext()->removeReference(*ref); |
| if (status != VX_SUCCESS) { |
| VXLOGE("removing %s in context fails, err:%d", (*ref)->getName(), status); |
| } |
| |
| status = (*ref)->destroy(); |
| if (status != VX_SUCCESS) { |
| VXLOGE("destroying %s fails, err:%d", (*ref)->getName(), status); |
| } |
| delete *ref; |
| *ref = NULL; |
| } |
| |
| return status; |
| } |
| |
| vx_size |
| ExynosVisionReference::sizeOfType(vx_enum type) |
| { |
| vx_uint32 i = 0; |
| vx_size size = 0ul; |
| for (i = 0; i < dimof(type_sizes); i++) { |
| if (type == type_sizes[i].type) { |
| size = type_sizes[i].size; |
| break; |
| } |
| } |
| return size; |
| } |
| |
| ExynosVisionReference::ExynosVisionReference(ExynosVisionContext* context, vx_type_e type, ExynosVisionReference* scope, vx_bool is_add_context) |
| { |
| EXYNOS_VISION_REF_IN(); |
| vx_char type_name[VX_MAX_REFERENCE_NAME]; |
| |
| m_global_lock.lock(); |
| m_id = ++m_ref_id_cnt; |
| if (getTypeName(type, type_name) == vx_false_e) |
| VXLOGE("unknown type(0x%X)", type); |
| |
| sprintf(m_name, "%s_%d", type_name, m_id); |
| m_global_lock.unlock(); |
| |
| m_context = context; |
| m_scope = scope; |
| m_magic = VX_MAGIC; |
| m_type = type; |
| m_internal_count = 0; |
| m_external_count = 0; |
| |
| m_creation_status = VX_SUCCESS; |
| |
| if (is_add_context) { |
| if (context->addReference(this) == vx_false_e) { |
| VXLOGE("Failed to add reference to global table"); |
| context->addLogEntry(context, VX_ERROR_NO_RESOURCES, "Failed to add to resources table\n"); |
| m_creation_status = VX_ERROR_NO_RESOURCES; |
| } |
| } |
| |
| VXLOGD2("Create %p, %s", this, m_name); |
| |
| EXYNOS_VISION_REF_OUT(); |
| } |
| |
| ExynosVisionReference::~ExynosVisionReference(void) |
| { |
| m_magic = VX_BAD_MAGIC; |
| |
| VXLOGD2("Delete %p, %s", this, m_name); |
| } |
| |
| vx_status |
| ExynosVisionReference::queryReference(vx_enum attribute, void *ptr, vx_size size) |
| { |
| vx_status status = VX_SUCCESS; |
| |
| switch (attribute) { |
| case VX_REF_ATTRIBUTE_COUNT: |
| if (VX_CHECK_PARAM(ptr, size, vx_uint32, 0x3)) |
| *(vx_uint32 *)ptr = m_external_count; |
| else |
| status = VX_ERROR_INVALID_PARAMETERS; |
| break; |
| case VX_REF_ATTRIBUTE_TYPE: |
| if (VX_CHECK_PARAM(ptr, size, vx_enum, 0x3)) |
| *(vx_enum *)ptr = m_type; |
| else |
| status = VX_ERROR_INVALID_PARAMETERS; |
| break; |
| default: |
| status = VX_ERROR_NOT_SUPPORTED; |
| break; |
| } |
| return status; |
| } |
| |
| vx_status |
| ExynosVisionReference::hint(vx_enum hint) |
| { |
| vx_status status = VX_SUCCESS; |
| |
| switch (hint) { |
| /*! \todo add hints to the sample implementation */ |
| case VX_HINT_SERIALIZE: |
| if (m_type == VX_TYPE_GRAPH) |
| ((ExynosVisionGraph*)this)->setSerialize(); |
| else |
| status = VX_ERROR_INVALID_TYPE; |
| break; |
| case VX_HINT_STREAM: |
| if (m_type == VX_TYPE_GRAPH) |
| ((ExynosVisionGraph*)this)->setExecMode(GRAPH_EXEC_STREAM); |
| else |
| status = VX_ERROR_INVALID_TYPE; |
| break; |
| default: |
| status = VX_ERROR_NOT_SUPPORTED; |
| break; |
| } |
| |
| return status; |
| } |
| |
| vx_status |
| ExynosVisionReference::directive(vx_enum directive) |
| { |
| vx_status status = VX_SUCCESS; |
| |
| switch (directive) { |
| /*! \todo add directive to the sample implementation */ |
| case VX_DIRECTIVE_DISABLE_LOGGING: |
| case VX_DIRECTIVE_ENABLE_LOGGING: |
| status = getContext()->setDirective(directive); |
| break; |
| case VX_DIRECTIVE_IMAGE_CONTINUOUS: |
| if (getType() == VX_TYPE_IMAGE) { |
| status = ((ExynosVisionImage*)this)->setDirective(directive); |
| if (status != VX_SUCCESS) { |
| VXLOGE("setting directive fails at %s, err:%s", getName(), status); |
| } |
| } else { |
| VXLOGE("continuous directive should apply to image object, not %s", getName()); |
| status = VX_ERROR_INVALID_REFERENCE; |
| } |
| break; |
| default: |
| status = VX_ERROR_NOT_SUPPORTED; |
| break; |
| } |
| |
| return status; |
| } |
| |
| vx_uint32 |
| ExynosVisionReference::incrementReference(vx_uint32 reftype, ExynosVisionReference *ref) |
| { |
| vx_uint32 count = 0u; |
| |
| Mutex::Autolock lock(m_internal_lock); |
| |
| if (reftype & VX_REF_EXTERNAL) { |
| m_external_count++; |
| } if (reftype & VX_REF_INTERNAL) { |
| m_internal_count++; |
| m_internal_object_list.push_back(ref); |
| } |
| |
| count = m_internal_count + m_external_count; |
| |
| return count; |
| } |
| |
| vx_uint32 |
| ExynosVisionReference::decrementReference(vx_uint32 reftype, ExynosVisionReference *referensing_obj) |
| { |
| Mutex::Autolock lock(m_internal_lock); |
| vx_uint32 result = 0xFFFFFFFF; |
| |
| if (reftype & VX_REF_INTERNAL) { |
| if (m_internal_count == 0) |
| VXLOGE("internal ref count is already zero, %s", getName()); |
| else |
| m_internal_count--; |
| |
| List<ExynosVisionReference*>::iterator ref_iter; |
| for (ref_iter=m_internal_object_list.begin(); ref_iter!=m_internal_object_list.end(); ref_iter++) { |
| if (*ref_iter == referensing_obj) |
| break; |
| } |
| |
| if (ref_iter != m_internal_object_list.end()) { |
| m_internal_object_list.erase(ref_iter); |
| } else { |
| if (referensing_obj != NULL) { |
| VXLOGE("releasing object is not corrent, %s releases %s", referensing_obj->getName(), this->getName()); |
| for (ref_iter=m_internal_object_list.begin(); ref_iter!=m_internal_object_list.end(); ref_iter++) { |
| VXLOGD("referencing object %s", (*ref_iter)->getName()); |
| } |
| } else { |
| VXLOGE("releasing object is NULL, NULL releases %s", this->getName()); |
| } |
| } |
| } |
| if (reftype & VX_REF_EXTERNAL) { |
| if (m_external_count == 0) { |
| VXLOGE("external ref count is already zero, %s", getName()); |
| } else { |
| m_external_count--; |
| } |
| } |
| |
| result = m_internal_count + m_external_count; |
| |
| return result; |
| } |
| |
| vx_status |
| ExynosVisionReference::destroy(void) |
| { |
| VXLOGE("reference type(0x%X) is not implemented yet", getType()); |
| return VX_FAILURE; |
| } |
| |
| void |
| ExynosVisionReference::displayInfo(vx_uint32 tab_num, vx_bool detail_info) |
| { |
| vx_char tap[MAX_TAB_NUM]; |
| |
| VXLOGD("%s[Referen][%d] ref:%s, refCnt:%d/%d", MAKE_TAB(tap, tab_num), detail_info, getName(), getInternalCnt(), getExternalCnt()); |
| } |
| |
| void |
| ExynosVisionReference::displayPerf(vx_uint32 tab_num, vx_bool detail_info) |
| { |
| vx_char tap[MAX_TAB_NUM]; |
| |
| VXLOGD("%s[Referen][%d] %s doesn't report performance data", MAKE_TAB(tap, tab_num), detail_info, getName()); |
| } |
| |
| vx_bool |
| ExynosVisionDataReference::checkWriteDependency(ExynosVisionDataReference *data_ref1, ExynosVisionDataReference *data_ref2) |
| { |
| if (data_ref1 == data_ref2) { |
| VXLOGE("write dependency, same object, ref1(%d), ref2(%d)", data_ref1->getId(), data_ref2->getId()); |
| return vx_true_e; |
| } |
| |
| /* write to layer then read pyramid */ |
| if (data_ref1->getType() == VX_TYPE_PYRAMID && data_ref2->getType() == VX_TYPE_IMAGE) { |
| if (data_ref1 == data_ref2->getScope()) { |
| VXLOGE("%s's scope is same with %s", data_ref2->getName(), data_ref1->getName()); |
| return vx_true_e; |
| } |
| } |
| |
| /* write to pyramid then read a layer */ |
| if (data_ref2->getType() == VX_TYPE_PYRAMID && data_ref1->getType() == VX_TYPE_IMAGE) { |
| if (data_ref2 == data_ref1->getScope()) { |
| VXLOGE("%s's ancestor is same with %s", data_ref1->getName(), data_ref2->getName()); |
| return vx_true_e; |
| } |
| } |
| |
| /* two images or ROIs */ |
| if (data_ref1->getType() == VX_TYPE_IMAGE && data_ref2->getType() == VX_TYPE_IMAGE) { |
| if (ExynosVisionImage::checkImageDependenct((ExynosVisionImage*)data_ref1, (ExynosVisionImage*)data_ref2)) { |
| VXLOGE("ref1(%d) and ref2 has same region of interest", data_ref1->getId(), data_ref2->getId()); |
| return vx_true_e; |
| } |
| } |
| |
| return vx_false_e; |
| } |
| |
| vx_bool |
| ExynosVisionDataReference::isValidDataReference(ExynosVisionReference *ref) |
| { |
| vx_bool ret = vx_false_e; |
| if (ref != NULL) { |
| if ((ref->m_magic == VX_MAGIC) && |
| ((vxIsValidType(ref->getType())) && ref->getType() != VX_TYPE_CONTEXT) && |
| (ExynosVisionContext::isValidContext(ref->getContext()) == vx_true_e)) { |
| switch(ref->getType()) { |
| case VX_TYPE_DELAY: |
| case VX_TYPE_LUT: |
| case VX_TYPE_DISTRIBUTION: |
| case VX_TYPE_PYRAMID: |
| case VX_TYPE_THRESHOLD: |
| case VX_TYPE_MATRIX: |
| case VX_TYPE_CONVOLUTION: |
| case VX_TYPE_SCALAR: |
| case VX_TYPE_ARRAY: |
| case VX_TYPE_IMAGE: |
| case VX_TYPE_REMAP: |
| ret = vx_true_e; |
| break; |
| default: |
| ret = vx_false_e; |
| break; |
| } |
| ret = vx_true_e; |
| } else { |
| VXLOGE("ref(%p) is not a valid reference", ref); |
| } |
| } else { |
| VXLOGE("reference was NULL"); |
| } |
| return ret; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::jointAlliance(ExynosVisionDataReference *data_ref1, ExynosVisionDataReference *data_ref2) |
| { |
| vx_status status = VX_SUCCESS; |
| |
| status |= data_ref1->registerAlliance(data_ref2); |
| status |= data_ref2->registerAlliance(data_ref1); |
| if (status != VX_SUCCESS) { |
| VXLOGE("register alliance fails"); |
| } |
| |
| return status; |
| } |
| |
| ExynosVisionDataReference::ExynosVisionDataReference(ExynosVisionContext* context, vx_type_e type, ExynosVisionReference* scope, |
| vx_bool is_add_context, vx_bool is_virtual) |
| : ExynosVisionReference(context, type, scope, is_add_context) |
| { |
| m_delay = NULL; |
| m_delay_slot_index = 0; |
| |
| m_is_virtual = is_virtual; |
| |
| m_res_type = RESOURCE_MNGR_NULL; |
| |
| m_is_allocated = vx_false_e; |
| |
| m_allocator_need_flag = vx_false_e; |
| m_allocator = NULL; |
| |
| m_kernel_count = 0; |
| m_access_count = 0; |
| } |
| |
| ExynosVisionDataReference::~ExynosVisionDataReference(void) |
| { |
| if (m_clone_object_map.size()) { |
| VXLOGE("clone map of %s is not freed", getName()); |
| } |
| |
| map<void*, ExynosVisionDataReference*>::iterator ref_iter; |
| for (ref_iter=m_clone_object_map.begin(); ref_iter!=m_clone_object_map.end(); ref_iter++) { |
| if ((*ref_iter).second) |
| delete (*ref_iter).second; |
| } |
| } |
| |
| vx_status |
| ExynosVisionDataReference::increaseKernelCount(void) |
| { |
| EXYNOS_VISION_REF_IN(); |
| Mutex::Autolock lock(m_internal_lock); |
| |
| m_kernel_count++; |
| |
| EXYNOS_VISION_REF_OUT(); |
| |
| return VX_SUCCESS; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::decreaseKernelCount(void) |
| { |
| EXYNOS_VISION_REF_IN(); |
| Mutex::Autolock lock(m_internal_lock); |
| |
| if (m_kernel_count != 0) { |
| m_kernel_count--; |
| } else { |
| VXLOGE("%s, kernel count is already zero", getName()); |
| displayInfo(0, vx_true_e); |
| return VX_FAILURE; |
| } |
| |
| EXYNOS_VISION_REF_OUT(); |
| |
| return VX_SUCCESS; |
| } |
| |
| vx_uint32 |
| ExynosVisionDataReference::increaseAccessCount(void) |
| { |
| EXYNOS_VISION_REF_IN(); |
| Mutex::Autolock lock(m_internal_lock); |
| |
| m_access_count++; |
| |
| EXYNOS_VISION_REF_OUT(); |
| |
| return m_access_count; |
| } |
| |
| vx_uint32 |
| ExynosVisionDataReference::decreaseAccessCount(void) |
| { |
| EXYNOS_VISION_REF_IN(); |
| Mutex::Autolock lock(m_internal_lock); |
| |
| if (m_access_count != 0) { |
| m_access_count--; |
| } else { |
| VXLOGE("%s, access count is already zero", getName()); |
| displayInfo(0, vx_true_e); |
| } |
| |
| EXYNOS_VISION_REF_OUT(); |
| |
| return m_access_count; |
| } |
| |
| vx_bool |
| ExynosVisionDataReference::connectNode(ExynosVisionGraph *graph, ExynosVisionNode *node, vx_uint32 node_index, enum vx_direction_e data_ref_direction) |
| { |
| EXYNOS_VISION_REF_IN(); |
| Mutex::Autolock lock(m_internal_lock); |
| |
| VXLOGD2("%s, add %s of %s", this->getName(), node->getName(), graph->getName()); |
| node_connect_info_t connect_info; |
| connect_info.node = node; |
| connect_info.node_index = node_index; |
| |
| if (data_ref_direction == VX_INPUT) { |
| m_output_node_list[graph].push_back(connect_info); |
| } else { |
| m_input_node_list[graph].push_back(connect_info); |
| } |
| |
| EXYNOS_VISION_REF_OUT(); |
| |
| return vx_true_e; |
| } |
| |
| vx_bool |
| ExynosVisionDataReference::disconnectNode(ExynosVisionGraph *graph, ExynosVisionNode *node, vx_uint32 node_index, enum vx_direction_e data_ref_direction) |
| { |
| EXYNOS_VISION_REF_IN(); |
| Mutex::Autolock lock(m_internal_lock); |
| |
| vx_bool result = vx_false_e; |
| |
| List<node_connect_info_t> *node_list; |
| List<node_connect_info_t>::iterator node_iter; |
| |
| VXLOGD2("%s disconnects %s of %s", this->getName(), node->getName(), graph->getName()); |
| if (data_ref_direction == VX_INPUT) |
| node_list = &m_output_node_list[graph]; |
| else |
| node_list = &m_input_node_list[graph]; |
| |
| if (node_list->size() == 0) { |
| result = vx_false_e; |
| VXLOGE("%s does not have any node of %s", getName(), graph->getName()); |
| |
| goto EXIT; |
| } |
| |
| /* a node could connect multiple way to same data reference */ |
| for (node_iter = node_list->begin(); node_iter != node_list->end(); node_iter++) { |
| if (((*node_iter).node == node) && ((*node_iter).node_index == node_index)){ |
| VXLOGD2("disconnect to %s", (*node_iter).node->getName()); |
| node_iter = node_list->erase(node_iter); |
| result = vx_true_e; |
| break; |
| } |
| } |
| |
| if (result != vx_true_e) |
| VXLOGE("%s is not found at %s", node->getName(), this->getName()); |
| |
| /* remove graph map if there is no node anymore */ |
| if (node_list->size() == 0) { |
| VXLOGD2("remove map of %s", graph->getName()); |
| if (data_ref_direction == VX_INPUT) |
| m_output_node_list.erase(graph); |
| else |
| m_input_node_list.erase(graph); |
| } |
| |
| EXIT: |
| EXYNOS_VISION_REF_OUT(); |
| |
| return result; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::registerAlliance(ExynosVisionDataReference *ref) |
| { |
| List<ExynosVisionDataReference*>::iterator ref_iter; |
| for (ref_iter=m_alliance_ref_list.begin(); ref_iter!=m_alliance_ref_list.end(); ref_iter++) { |
| if (*ref_iter == ref) { |
| VXLOGE("%s is already alliance with %s", ref->getName(), this->getName()); |
| return VX_FAILURE; |
| } |
| } |
| |
| m_alliance_ref_list.push_back(ref); |
| |
| return VX_SUCCESS; |
| } |
| |
| vx_uint32 |
| ExynosVisionDataReference::getDirectInputNodeNum(ExynosVisionGraph *graph) |
| { |
| EXYNOS_VISION_REF_IN(); |
| Mutex::Autolock lock(m_internal_lock); |
| |
| vx_uint32 count; |
| |
| count = m_input_node_list[graph].size(); |
| |
| EXYNOS_VISION_REF_OUT(); |
| |
| return count; |
| } |
| |
| vx_uint32 |
| ExynosVisionDataReference::getDirectOutputNodeNum(ExynosVisionGraph *graph) |
| { |
| EXYNOS_VISION_REF_IN(); |
| Mutex::Autolock lock(m_internal_lock); |
| |
| vx_uint32 count; |
| |
| count = m_output_node_list[graph].size(); |
| |
| EXYNOS_VISION_REF_OUT(); |
| |
| return count; |
| } |
| |
| vx_uint32 |
| ExynosVisionDataReference::getIndirectInputNodeNum(ExynosVisionGraph *graph) |
| { |
| vx_uint32 input_node_num = getDirectInputNodeNum(graph); |
| |
| List<ExynosVisionDataReference*>::iterator ref_iter; |
| for (ref_iter=m_alliance_ref_list.begin(); ref_iter!=m_alliance_ref_list.end(); ref_iter++) { |
| input_node_num += (*ref_iter)->getDirectInputNodeNum(graph); |
| } |
| |
| return input_node_num; |
| } |
| |
| vx_uint32 |
| ExynosVisionDataReference::getIndirectOutputNodeNum(ExynosVisionGraph *graph) |
| { |
| vx_uint32 output_node_num = getDirectOutputNodeNum(graph); |
| |
| List<ExynosVisionDataReference*>::iterator ref_iter; |
| for (ref_iter=m_alliance_ref_list.begin(); ref_iter!=m_alliance_ref_list.end(); ref_iter++) { |
| output_node_num += (*ref_iter)->getDirectOutputNodeNum(graph); |
| } |
| |
| return output_node_num; |
| } |
| |
| ExynosVisionNode* |
| ExynosVisionDataReference::getDirectOutputNode(ExynosVisionGraph *graph, vx_uint32 node_idx) |
| { |
| EXYNOS_VISION_REF_IN(); |
| Mutex::Autolock lock(m_internal_lock); |
| |
| List<node_connect_info_t> *node_list = &m_output_node_list[graph]; |
| |
| if (node_list->size() < (node_idx+1)) { |
| VXLOGE("out of bound node index:%d", node_idx); |
| return NULL; |
| } |
| |
| List<node_connect_info_t>::iterator iter_pos = node_list->begin(); |
| for (vx_uint32 i = 0; i<node_idx; i++, iter_pos++); |
| |
| ExynosVisionNode *node = (*iter_pos).node; |
| EXYNOS_VISION_REF_OUT(); |
| |
| return node; |
| } |
| |
| ExynosVisionNode* |
| ExynosVisionDataReference::getIndirectOutputNode(ExynosVisionGraph *graph, vx_uint32 node_idx) |
| { |
| if (node_idx < getDirectOutputNodeNum(graph)) { |
| return this->getDirectOutputNode(graph, node_idx); |
| } |
| |
| vx_uint32 remained_idx = node_idx - getDirectOutputNodeNum(graph); |
| |
| List<ExynosVisionDataReference*>::iterator ref_iter; |
| for (ref_iter=m_alliance_ref_list.begin(); ref_iter!=m_alliance_ref_list.end(); ref_iter++) { |
| if (remained_idx < (*ref_iter)->getDirectOutputNodeNum(graph)) { |
| return (*ref_iter)->getDirectOutputNode(graph, remained_idx); |
| } |
| remained_idx -= (*ref_iter)->getDirectOutputNodeNum(graph); |
| } |
| |
| VXLOGE("can't find proper connection"); |
| |
| return NULL; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::allocateMemory(void) |
| { |
| vx_enum res_type; |
| struct resource_param res_param; |
| vx_status status = VX_SUCCESS; |
| |
| if (m_is_allocated == vx_true_e) { |
| VXLOGE("already allocated memory %s", getName()); |
| status = VX_FAILURE; |
| goto EXIT; |
| } |
| |
| if (m_is_virtual == vx_true_e) { |
| ExynosVisionReference *scope = getScope(); |
| if (scope->getType() != VX_TYPE_GRAPH) { |
| VXLOGE("%s, virtual data object should be belong to graph", getName()); |
| status = VX_FAILURE; |
| goto EXIT; |
| } |
| |
| if (((ExynosVisionGraph*)scope)->getExecMode() == GRAPH_EXEC_STREAM) { |
| res_type = RESOURCE_MNGR_SLOT; |
| res_param.param.slot_param.slot_num = DEFAULT_SLOT_NUM; |
| } else { |
| res_type = RESOURCE_MNGR_SOLID; |
| } |
| } else { |
| res_type = RESOURCE_MNGR_SOLID; |
| } |
| |
| status = allocateMemory(res_type, &res_param); |
| if (status != VX_SUCCESS) { |
| VXLOGE("allocating memory fails, err:%d", status); |
| } |
| |
| EXIT: |
| |
| return status; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::allocateMemory(vx_enum res_type, struct resource_param *param) |
| { |
| VXLOGE("%s couldn't allocate memory, res_type:%d, param:%p", getName(), res_type, param); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::triggerDoneEventIndirect(ExynosVisionGraph *graph, vx_uint32 frame_cnt) |
| { |
| vx_status status = VX_SUCCESS; |
| |
| status = this->triggerDoneEventDirect(graph, frame_cnt); |
| if (status != VX_SUCCESS) { |
| VXLOGE("%s, trigger done event fails", this->getName()); |
| } else { |
| List<ExynosVisionDataReference*>::iterator ref_iter; |
| for (ref_iter=m_alliance_ref_list.begin(); ref_iter!=m_alliance_ref_list.end(); ref_iter++) { |
| status = (*ref_iter)->triggerDoneEventDirect(graph, frame_cnt); |
| if (status != VX_SUCCESS) { |
| VXLOGE("%s, trigger done event fails", (*ref_iter)->getName()); |
| break; |
| } |
| } |
| } |
| |
| return status; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::triggerDoneEventDirect(ExynosVisionGraph *graph, vx_uint32 frame_cnt) |
| { |
| vx_status status = VX_SUCCESS; |
| |
| List<node_connect_info_t> *output_node_list = &m_output_node_list[graph]; |
| List<node_connect_info_t>::iterator node_iter; |
| |
| for (node_iter=output_node_list->begin(); node_iter!=output_node_list->end(); node_iter++) { |
| ExynosVisionSubgraph *subgraph = (*node_iter).node->getSubgraph(); |
| if (subgraph == NULL) { |
| VXLOGE("cannot find subgraph from %s", (*node_iter).node->getName()); |
| status = VX_FAILURE; |
| break; |
| } else { |
| subgraph->pushDoneEvent(frame_cnt, this, (*node_iter).node_index); |
| } |
| } |
| |
| return status; |
| } |
| |
| ExynosVisionDataReference* |
| ExynosVisionDataReference::getInputExclusiveRef(vx_uint32 frame_cnt, vx_bool *ret_data_valid) |
| { |
| if (m_res_type == RESOURCE_MNGR_SOLID) { |
| /* solid and exclusive input is always valid because it comes from application */ |
| *ret_data_valid = vx_true_e; |
| return this; |
| } else { |
| VXLOGE("exclusive reference of %s can't be resource type:%d, frame_%d, &data_valid:%p", getName(), m_res_type, frame_cnt, ret_data_valid); |
| *ret_data_valid = vx_false_e; |
| return NULL; |
| } |
| } |
| |
| vx_status |
| ExynosVisionDataReference::putInputExclusiveRef(vx_uint32 frame_cnt) |
| { |
| if (m_res_type == RESOURCE_MNGR_SOLID) { |
| return VX_SUCCESS; |
| } else { |
| VXLOGE("exclusive reference of %s can't be resource type:%d, frame_%d", getName(), m_res_type, frame_cnt); |
| return VX_FAILURE; |
| } |
| } |
| |
| ExynosVisionDataReference* |
| ExynosVisionDataReference::getOutputExclusiveRef(vx_uint32 frame_cnt) |
| { |
| if (m_res_type == RESOURCE_MNGR_SOLID) { |
| return this; |
| } else { |
| VXLOGE("exclusive reference of %s can't be resource type:%d, frame_%d", getName(), m_res_type, frame_cnt); |
| return NULL; |
| } |
| } |
| |
| vx_status |
| ExynosVisionDataReference::putOutputExclusiveRef(vx_uint32 frame_cnt, vx_bool data_valid) |
| { |
| if (m_res_type == RESOURCE_MNGR_SOLID) { |
| return VX_SUCCESS; |
| } else { |
| VXLOGE("exclusive reference cf %s an't be resource type:%d, frame_%d, data_valid:%d", getName(), m_res_type, frame_cnt, data_valid); |
| return VX_FAILURE; |
| } |
| } |
| |
| ExynosVisionDataReference* |
| ExynosVisionDataReference::getInputShareRef(vx_uint32 frame_cnt, vx_bool *ret_data_valid) |
| { |
| VXLOGE("%s couldn't be shared reference, frame:%d, &data_valid:%p", getName(), frame_cnt, ret_data_valid); |
| return NULL; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::putInputShareRef(vx_uint32 frame_cnt) |
| { |
| VXLOGE("%s couldn't be shared reference, frame:%d", getName(), frame_cnt); |
| return VX_FAILURE; |
| } |
| |
| ExynosVisionDataReference* |
| ExynosVisionDataReference::getOutputShareRef(vx_uint32 frame_cnt) |
| { |
| VXLOGE("%s couldn't be shared reference, frame:%d", getName(), frame_cnt); |
| return NULL; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::putOutputShareRef(vx_uint32 frame_cnt, vx_uint32 demand_num, vx_bool data_valid) |
| { |
| VXLOGE("%s couldn't be shared reference, frame:%d, demand:%d, data_valid:%d", getName(), frame_cnt, demand_num, data_valid); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::allocateResource(default_resource_t **ret_resource) |
| { |
| VXLOGE("%s doesn't support this function, empty res:%p", getName(), ret_resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::allocateResource(image_resource_t **ret_resource) |
| { |
| VXLOGE("%s doesn't support this function, empty res:%p", getName(), ret_resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::allocateResource(pyramid_resource_t **ret_resource) |
| { |
| VXLOGE("%s doesn't support this function, empty res:%p", getName(), ret_resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::allocateResource(lut_resource_t **ret_resource) |
| { |
| VXLOGE("%s doesn't support this function, empty res:%p", getName(), ret_resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::allocateResource(empty_resource_t **ret_resource) |
| { |
| VXLOGE("%s doesn't support this function, empty res:%p", getName(), ret_resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::allocateResource(convolution_resource_t **ret_resource) |
| { |
| VXLOGE("%s doesn't support this function, empty res:%p", getName(), ret_resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::freeResource(default_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::freeResource(image_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::freeResource(pyramid_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::freeResource(lut_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::freeResource(empty_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::freeResource(convolution_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::createCloneObject(default_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::createCloneObject(image_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::createCloneObject(pyramid_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::createCloneObject(lut_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::createCloneObject(empty_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::createCloneObject(convolution_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::destroyCloneObject(default_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::destroyCloneObject(image_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::destroyCloneObject(pyramid_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::destroyCloneObject(lut_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::destroyCloneObject(empty_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| vx_status |
| ExynosVisionDataReference::destroyCloneObject(convolution_resource_t* resource) |
| { |
| VXLOGE("%s doesn't support this function, res:%p", getName(), resource); |
| return VX_FAILURE; |
| } |
| |
| void |
| ExynosVisionDataReference::displayConn(vx_uint32 tab_num) |
| { |
| vx_char tap[MAX_TAB_NUM]; |
| |
| map<ExynosVisionGraph*, List<node_connect_info_t>>::iterator map_iter; |
| for (map_iter=m_input_node_list.begin(); map_iter!=m_input_node_list.end(); map_iter++) { |
| List<node_connect_info_t> *node_list = &(map_iter->second); |
| List<node_connect_info_t>::iterator node_iter; |
| for (node_iter=node_list->begin(); node_iter!=node_list->end(); node_iter++) |
| VXLOGI("%s input: %s at %s", MAKE_TAB(tap, tab_num), (*node_iter).node->getName(), map_iter->first->getName()); |
| } |
| for (map_iter=m_output_node_list.begin(); map_iter!=m_output_node_list.end(); map_iter++) { |
| List<node_connect_info_t> *node_list = &(map_iter->second); |
| List<node_connect_info_t>::iterator node_iter; |
| for (node_iter=node_list->begin(); node_iter!=node_list->end(); node_iter++) |
| VXLOGI("%s output: %s at %s", MAKE_TAB(tap, tab_num), (*node_iter).node->getName(), map_iter->first->getName()); |
| } |
| } |
| |
| void |
| ExynosVisionDataReference::displayInfo(vx_uint32 tab_num, vx_bool detail_info) |
| { |
| vx_char tap[MAX_TAB_NUM]; |
| |
| VXLOGI("%s[RefData][%d] ref:%s(%p), refCnt:%d/%d", MAKE_TAB(tap, tab_num), detail_info, getName(), this, getInternalCnt(), getExternalCnt()); |
| |
| LOG_FLUSH_TIME(); |
| |
| if (detail_info) |
| displayConn(tab_num); |
| } |
| |
| }; /* namespace android */ |