1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "slide_window_processor.h"
17
18 #include <memory>
19
20 #include "aie_log.h"
21 #include "aie_macros.h"
22 #include "aie_retcode_inner.h"
23 #include "securec.h"
24
25 using namespace OHOS::AI::Feature;
26
27 namespace {
28 const uint8_t ILLEGAL_BUFFER_MULTIPLIER = 0;
29 }
30
SlideWindowProcessor()31 SlideWindowProcessor::SlideWindowProcessor()
32 : isInitialized_(false),
33 workBuffer_(nullptr),
34 inputFeature_(nullptr),
35 inType_(UNKNOWN),
36 typeSize_(0),
37 startIndex_(0),
38 initIndex_(0),
39 bufferSize_(0),
40 windowSize_(0),
41 stepSize_(0) {}
42
~SlideWindowProcessor()43 SlideWindowProcessor::~SlideWindowProcessor()
44 {
45 Release();
46 }
47
Init(const FeatureProcessorConfig * config)48 int32_t SlideWindowProcessor::Init(const FeatureProcessorConfig *config)
49 {
50 if (isInitialized_) {
51 HILOGE("[SlideWindowProcessor]Fail to init more than once. Release it, then try again");
52 return RETCODE_FAILURE;
53 }
54 if (config == nullptr) {
55 HILOGE("[SlideWindowProcessor]Fail to init with null config");
56 return RETCODE_FAILURE;
57 }
58 auto localConfig = *(static_cast<const SlideWindowProcessorConfig *>(config));
59 if (localConfig.dataType == UNKNOWN) {
60 HILOGE("[SlideWindowProcessor]Fail with unsupported dataType[UNKNOWN]");
61 return RETCODE_FAILURE;
62 }
63 if (localConfig.windowSize < localConfig.stepSize) {
64 HILOGE("[SlideWindowProcessor]Illegal configuration. The stepSize cannot be greater than windowSize");
65 return RETCODE_FAILURE;
66 }
67 if (localConfig.bufferMultiplier == ILLEGAL_BUFFER_MULTIPLIER) {
68 HILOGE("[SlideWindowProcessor]Illegal configuration. The bufferMultiplier cannot be zero");
69 return RETCODE_FAILURE;
70 }
71 inType_ = localConfig.dataType;
72 typeSize_ = CONVERT_DATATYPE_TO_SIZE(inType_);
73 windowSize_ = localConfig.windowSize;
74 stepSize_ = localConfig.stepSize * typeSize_;
75 initIndex_ = (windowSize_ * typeSize_) - stepSize_;
76 startIndex_ = initIndex_;
77 bufferSize_ = (windowSize_ * localConfig.bufferMultiplier) * typeSize_;
78 if (windowSize_ > MAX_SAMPLE_SIZE) {
79 HILOGE("[SlideWindowProcessor]The required memory size is larger than MAX_SAMPLE_SIZE[%zu]",
80 MAX_SAMPLE_SIZE);
81 return RETCODE_FAILURE;
82 }
83 AIE_NEW(workBuffer_, char[bufferSize_]);
84 if (workBuffer_ == nullptr) {
85 HILOGE("[SlideWindowProcessor]Fail to allocate memory for workBuffer");
86 return RETCODE_FAILURE;
87 }
88 (void)memset_s(workBuffer_, bufferSize_, 0, bufferSize_);
89 inputFeature_ = workBuffer_;
90 isInitialized_ = true;
91 return RETCODE_SUCCESS;
92 }
93
Release()94 void SlideWindowProcessor::Release()
95 {
96 AIE_DELETE_ARRAY(workBuffer_);
97 inputFeature_ = nullptr;
98 isInitialized_ = false;
99 }
100
Process(const FeatureData & input,FeatureData & output)101 int32_t SlideWindowProcessor::Process(const FeatureData &input, FeatureData &output)
102 {
103 if (!isInitialized_) {
104 HILOGE("[SlideWindowProcessor]Fail to process without successfully init");
105 return RETCODE_FAILURE;
106 }
107 if (input.dataType != inType_) {
108 HILOGE("[SlideWindowProcessor]Fail with unmatched input dataType");
109 return RETCODE_FAILURE;
110 }
111 if (input.data == nullptr || input.size == 0) {
112 HILOGE("[SlideWindowProcessor]Fail with NULL input");
113 return RETCODE_FAILURE;
114 }
115 size_t inputBytes = input.size * typeSize_;
116 if (inputBytes != stepSize_) {
117 HILOGE("[SlideWindowProcessor]Fail with unmatched input dataSize, expected [%zu]", stepSize_ / typeSize_);
118 return RETCODE_FAILURE;
119 }
120 if (output.data != nullptr || output.size != 0) {
121 HILOGE("[SlideWindowProcessor]Fail with non-empty output");
122 return RETCODE_FAILURE;
123 }
124 output.dataType = inType_;
125 // Update the last window by the input data of new window
126 errno_t retCode = memcpy_s(workBuffer_ + startIndex_, bufferSize_ - startIndex_, input.data, inputBytes);
127 if (retCode != EOK) {
128 HILOGE("[SlideWindowProcessor]Fail to copy input data to workBuffer [%d]", retCode);
129 return RETCODE_FAILURE;
130 }
131 output.data = inputFeature_;
132 output.size = windowSize_;
133 startIndex_ += stepSize_;
134 // Slide to the next position
135 inputFeature_ += stepSize_;
136 // Post-processing
137 if (bufferSize_ - startIndex_ < stepSize_) {
138 retCode = memmove_s(workBuffer_, bufferSize_, inputFeature_, initIndex_);
139 if (retCode != EOK) {
140 HILOGE("[SlideWindowProcessor]Fail with memory move. Error code[%d]", retCode);
141 return RETCODE_FAILURE;
142 }
143 startIndex_ = initIndex_;
144 inputFeature_ = workBuffer_;
145 }
146 return RETCODE_SUCCESS;
147 }