• 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 
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