1 /*
2 * Copyright (c) 2020-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 "buffer_source.h"
17 #include "securec.h"
18 #include "media_log.h"
19
20 #ifdef __cplusplus
21 #if __cplusplus
22 extern "C" {
23 #endif
24 #endif /* __cplusplus */
25
26 const int32_t EOS_LEN = 4; /* set eos len 4, ensure the eos flag can be read */
27 const uint32_t BUFFER_SOURCE_FLAG_EOS = 4; /* STREAM_FLAG_EOS */
28
29 #define CHK_NULL_RETURN( ptr) \
30 do { \
31 if (ptr == nullptr) { \
32 MEDIA_ERR_LOG("input param null"); \
33 return -1; \
34 } \
35 } while (0)
36
BufferSource(void)37 BufferSource::BufferSource(void)
38 {
39 inited_ = false;
40
41 idleBuffer_.clear();
42 filledBuffer_.clear();
43 if (memset_s(buffer_, sizeof(BufferInfo) * QUEUE_SIZE, 0, sizeof(BufferInfo) * QUEUE_SIZE) != 0) {
44 MEDIA_ERR_LOG("BufferSource memset_s failed");
45 }
46 }
47
~BufferSource(void)48 BufferSource::~BufferSource(void)
49 {
50 int i;
51 if (inited_ == false) {
52 return;
53 }
54 idleBuffer_.clear();
55 filledBuffer_.clear();
56 for (i = 0; i < QUEUE_SIZE; i++) {
57 if (buffer_[i].virAddr != nullptr) {
58 free(buffer_[i].virAddr);
59 buffer_[i].virAddr = nullptr;
60 }
61 }
62 inited_ = false;
63 }
64
Init(void)65 int BufferSource::Init(void)
66 {
67 int i;
68
69 for (i = 0; i < QUEUE_SIZE; i++) {
70 buffer_[i].virAddr = malloc(BUFFER_SIZE);
71 if (buffer_[i].virAddr == nullptr) {
72 MEDIA_ERR_LOG("BufferSource::Init, malloc failed\n");
73 goto failed;
74 }
75 buffer_[i].phyAddr = 0;
76 buffer_[i].fd = -1;
77 buffer_[i].bufLen = BUFFER_SIZE;
78 buffer_[i].offset = 0;
79 buffer_[i].size = BUFFER_SIZE;
80 buffer_[i].idx = i;
81
82 QueBuffer buffer;
83 buffer.idx = i;
84 buffer.flag = 0;
85 buffer.offset = 0;
86 buffer.size = 0;
87 buffer.timestamp = 0;
88 QueIdleBuffer(&buffer);
89 }
90 inited_ = true;
91 MEDIA_INFO_LOG("idleQue size:%d",idleBuffer_.size());
92 return 0;
93 failed:
94 for (i = 0; i < QUEUE_SIZE; i++) {
95 if (buffer_[i].virAddr != nullptr) {
96 free(buffer_[i].virAddr);
97 buffer_[i].virAddr = nullptr;
98 }
99 }
100 idleBuffer_.clear();
101 return -1;
102 }
103
GetQueSize(void)104 int BufferSource::GetQueSize(void)
105 {
106 return QUEUE_SIZE;
107 }
108
GetBufferInfo(int idx,BufferInfo * info)109 int BufferSource::GetBufferInfo(int idx, BufferInfo* info)
110 {
111 CHK_NULL_RETURN(info);
112 if (idx < 0 || idx >= QUEUE_SIZE) {
113 return -1;
114 }
115 *info = buffer_[idx];
116 return 0;
117 }
118
QueIdleBuffer(const QueBuffer * buffer)119 int BufferSource::QueIdleBuffer(const QueBuffer *buffer)
120 {
121 std::lock_guard<std::mutex> lock(idleQueMutex_);
122 CHK_NULL_RETURN(buffer);
123 idleBuffer_.push_back(*buffer);
124 return 0;
125 }
126
DequeIdleBuffer(QueBuffer * buffer,int timeOut)127 int BufferSource::DequeIdleBuffer(QueBuffer* buffer, int timeOut)
128 {
129 std::lock_guard<std::mutex> lock(idleQueMutex_);
130 CHK_NULL_RETURN(buffer);
131 if (idleBuffer_.empty() != 0) {
132 return -1;
133 }
134 *buffer = idleBuffer_[0];
135 idleBuffer_.erase(idleBuffer_.begin());
136 return 0;
137 }
138
GetIdleQueSize(void)139 size_t BufferSource::GetIdleQueSize(void)
140 {
141 size_t size;
142 std::lock_guard<std::mutex> lock(idleQueMutex_);
143 size = idleBuffer_.size();
144 return size;
145 }
146
QueFilledBuffer(const QueBuffer * buffer)147 int BufferSource::QueFilledBuffer(const QueBuffer *buffer)
148 {
149 std::lock_guard<std::mutex> lock(filledQueMutex_);
150 CHK_NULL_RETURN(buffer);
151 filledBuffer_.push_back(*buffer);
152 return 0;
153 }
154
DequeFilledBuffer(QueBuffer * buffer,int timeOut)155 int BufferSource::DequeFilledBuffer(QueBuffer* buffer, int timeOut)
156 {
157 std::lock_guard<std::mutex> lock(filledQueMutex_);
158 CHK_NULL_RETURN(buffer);
159 if (filledBuffer_.empty() != 0) {
160 return -1;
161 }
162 *buffer = filledBuffer_[0];
163 filledBuffer_.erase(filledBuffer_.begin());
164 return 0;
165 }
166
GetFilledQueSize(void)167 size_t BufferSource::GetFilledQueSize(void)
168 {
169 size_t size;
170 std::lock_guard<std::mutex> lock(filledQueMutex_);
171 size = filledBuffer_.size();
172 return size;
173 }
174
GetFilledQueDataSize(void)175 int32_t BufferSource::GetFilledQueDataSize(void)
176 {
177 uint32_t i;
178 size_t size;
179 int32_t len = 0;
180 std::lock_guard<std::mutex> lock(filledQueMutex_);
181 size = filledBuffer_.size();
182 for (i = 0; i < size; i++) {
183 len += filledBuffer_[i].size;
184 }
185 /* fix the issue last buffer have not been read, when the buffer only include a eos flag */
186 if (size == 1 && len == 0 && filledBuffer_[0].flag == BUFFER_SOURCE_FLAG_EOS) {
187 len = EOS_LEN;
188 }
189 return len;
190 }
191
GetFilledBuffer(size_t idx,QueBuffer * buffer)192 int BufferSource::GetFilledBuffer(size_t idx, QueBuffer* buffer)
193 {
194 std::lock_guard<std::mutex> lock(filledQueMutex_);
195 size_t queSize;
196 CHK_NULL_RETURN(buffer);
197 queSize = filledBuffer_.size();
198 if (queSize <= idx) {
199 return -1;
200 }
201 *buffer = filledBuffer_[idx];
202 return 0;
203 }
204
205 #ifdef __cplusplus
206 #if __cplusplus
207 }
208 #endif
209 #endif /* __cplusplus */
210