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