• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Shenzhen Kaihong DID 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_manager.h"
17 #include <securec.h>
18 
19 template <class T>
BufferManager()20 BufferManager<T>::BufferManager()
21 {
22     OsalMutexInit(&bufferQueueLock);
23     OsalMutexInit(&usedBufferQueueLock);
24 }
25 
26 template <class T>
~BufferManager()27 BufferManager<T>::~BufferManager()
28 {
29     OsalMutexDestroy(&bufferQueueLock);
30     OsalMutexDestroy(&usedBufferQueueLock);
31 }
32 
33 template <class T>
Stop()34 void BufferManager<T>::Stop()
35 {
36     status = CODEC_STATUS_STOPPED;
37 }
38 
39 template <class T>
GetBuffer(uint32_t timeoutMs,bool isChecking)40 T* BufferManager<T>::GetBuffer(uint32_t timeoutMs, bool isChecking)
41 {
42     OsalMutexLock(&bufferQueueLock);
43     T *inputData = nullptr;
44     inputData = PollBufferQueue(isChecking);
45     if (inputData == nullptr) {
46         if (timeoutMs == HDF_WAIT_FOREVER) {
47             // release lock and wait here, and check again later when notified
48             pthread_cond_wait(&inputCond, (pthread_mutex_t *)bufferQueueLock.realMutex);
49             inputData = PollBufferQueue(isChecking);
50         } else if (timeoutMs > 0) {
51             struct timespec time = {0};
52             ConstructTimespec(&time, timeoutMs);
53             // release lock and wait here, and check again later when notified or timeout
54             pthread_cond_timedwait(&inputCond, (pthread_mutex_t *)bufferQueueLock.realMutex, &time);
55             inputData = PollBufferQueue(isChecking);
56         }
57     }
58     OsalMutexUnlock(&bufferQueueLock);
59 
60     return inputData;
61 }
62 
63 template <class T>
GetUsedBuffer(uint32_t timeoutMs,bool isChecking)64 T* BufferManager<T>::GetUsedBuffer(uint32_t timeoutMs, bool isChecking)
65 {
66     OsalMutexLock(&usedBufferQueueLock);
67     T *outputData = nullptr;
68     outputData = PollUsedBufferQueue(isChecking);
69     if (outputData == nullptr) {
70         if (timeoutMs == HDF_WAIT_FOREVER) {
71             // release lock and wait here, and check again later when notified
72             pthread_cond_wait(&outputCond, (pthread_mutex_t *)usedBufferQueueLock.realMutex);
73             outputData = PollUsedBufferQueue(isChecking);
74         } else if (timeoutMs > 0) {
75             struct timespec time = {0};
76             ConstructTimespec(&time, timeoutMs);
77             // release lock and wait here, and check again later when notified or timeout
78             pthread_cond_timedwait(&outputCond, (pthread_mutex_t *)usedBufferQueueLock.realMutex, &time);
79             outputData = PollUsedBufferQueue(isChecking);
80         }
81     }
82     OsalMutexUnlock(&usedBufferQueueLock);
83 
84     return outputData;
85 }
86 
87 template <class T>
ConstructTimespec(struct timespec * time,uint32_t timeoutMs)88 void BufferManager<T>::ConstructTimespec(struct timespec *time, uint32_t timeoutMs)
89 {
90     memset_s(time, sizeof(timespec), 0, sizeof(timespec));
91     clock_gettime(CLOCK_REALTIME, time);
92     time->tv_sec += static_cast<int32_t>(timeoutMs) / HDF_KILO_UNIT;
93     time->tv_nsec += (static_cast<int32_t>(timeoutMs) % HDF_KILO_UNIT) * HDF_KILO_UNIT * HDF_KILO_UNIT;
94     if (time->tv_nsec >= HDF_NANO_UNITS) {
95         time->tv_nsec -= HDF_NANO_UNITS;
96         time->tv_sec += 1;
97     }
98 }
99 
100 template <class T>
PollBufferQueue(bool isChecking)101 T* BufferManager<T>::PollBufferQueue(bool isChecking)
102 {
103     T *info = nullptr;
104     if (bufferQueue.size() == 0) {
105         return nullptr;
106     }
107     info = bufferQueue.front();
108     if (!isChecking) {
109         bufferQueue.pop();
110     }
111     return info;
112 }
113 
114 template <class T>
PollUsedBufferQueue(bool isChecking)115 T* BufferManager<T>::PollUsedBufferQueue(bool isChecking)
116 {
117     T *info = nullptr;
118     if (usedBufferQueue.size() == 0) {
119         return nullptr;
120     }
121     info = usedBufferQueue.front();
122     if (!isChecking) {
123         usedBufferQueue.pop();
124     }
125     return info;
126 }
127 
128 template <class T>
PutBuffer(T * info)129 void BufferManager<T>::PutBuffer(T *info)
130 {
131     OsalMutexLock(&bufferQueueLock);
132     bufferQueue.push(info);
133     pthread_cond_signal(&inputCond);
134     OsalMutexUnlock(&bufferQueueLock);
135 }
136 
137 template <class T>
PutUsedBuffer(T * info)138 void BufferManager<T>::PutUsedBuffer(T *info)
139 {
140     OsalMutexLock(&usedBufferQueueLock);
141     usedBufferQueue.push(info);
142     pthread_cond_signal(&outputCond);
143     OsalMutexUnlock(&usedBufferQueueLock);
144 }
145 
146 template class BufferManager<CodecBuffer>;
147