Line data Source code
1 : /* 2 : * Copyright (C) 2004-2024 Savoir-faire Linux Inc. 3 : * 4 : * This program is free software: you can redistribute it and/or modify 5 : * it under the terms of the GNU General Public License as published by 6 : * the Free Software Foundation, either version 3 of the License, or 7 : * (at your option) any later version. 8 : * 9 : * This program is distributed in the hope that it will be useful, 10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 : * GNU General Public License for more details. 13 : * 14 : * You should have received a copy of the GNU General Public License 15 : * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 : */ 17 : #pragma once 18 : 19 : #include "audio_format.h" 20 : #include "media_buffer.h" 21 : #include "noncopyable.h" 22 : 23 : #include <map> 24 : #include <set> 25 : #include <string> 26 : #include <mutex> 27 : #include <memory> 28 : 29 : namespace jami { 30 : 31 : class RingBuffer; 32 : 33 : class RingBufferPool 34 : { 35 : public: 36 : static const char* const DEFAULT_ID; 37 : 38 : RingBufferPool(); 39 : ~RingBufferPool(); 40 : 41 33 : int getInternalSamplingRate() const { return internalAudioFormat_.sample_rate; } 42 : 43 665 : AudioFormat getInternalAudioFormat() const { return internalAudioFormat_; } 44 : 45 : void setInternalSamplingRate(unsigned sr); 46 : 47 : void setInternalAudioFormat(AudioFormat format); 48 : 49 : /** 50 : * Bind together two audio streams 51 : */ 52 : void bindRingbuffers(const std::string& ringbufferId1, const std::string& ringbufferId2); 53 : 54 : /** 55 : * Add a new ringbufferId to unidirectional outgoing stream 56 : * \param ringbufferId New ringbufferId to be added for this stream 57 : * \param processId Process that require this stream 58 : */ 59 : void bindHalfDuplexOut(const std::string& processId, const std::string& ringbufferId); 60 : 61 : /** 62 : * Unbind two ringbuffers 63 : */ 64 : void unbindRingbuffers(const std::string& ringbufferId1, const std::string& ringbufferId2); 65 : 66 : /** 67 : * Unbind a unidirectional stream 68 : */ 69 : void unBindHalfDuplexOut(const std::string& process_id, const std::string& ringbufferId); 70 : 71 : void unBindAllHalfDuplexOut(const std::string& ringbufferId); 72 : 73 : void unBindAll(const std::string& ringbufferId); 74 : 75 : bool waitForDataAvailable(const std::string& ringbufferId, 76 : const std::chrono::microseconds& max_wait) const; 77 : 78 : std::shared_ptr<AudioFrame> getData(const std::string& ringbufferId); 79 : 80 : std::shared_ptr<AudioFrame> getAvailableData(const std::string& ringbufferId); 81 : 82 : size_t availableForGet(const std::string& ringbufferId) const; 83 : 84 : size_t discard(size_t toDiscard, const std::string& ringbufferId); 85 : 86 : void flush(const std::string& ringbufferId); 87 : 88 : void flushAllBuffers(); 89 : 90 : /** 91 : * Create a new ringbuffer with a default readoffset. 92 : * This class keeps a weak reference on returned pointer, 93 : * so the caller is responsible of the referred instance. 94 : */ 95 : std::shared_ptr<RingBuffer> createRingBuffer(const std::string& id); 96 : 97 : /** 98 : * Obtain a shared pointer on a RingBuffer given by its ID. 99 : * If the ID doesn't match to any RingBuffer, the shared pointer 100 : * is empty. This non-const version flushes internal weak pointers 101 : * if the ID was used and the associated RingBuffer has been deleted. 102 : */ 103 : std::shared_ptr<RingBuffer> getRingBuffer(const std::string& id); 104 : 105 : /** 106 : * Works as non-const getRingBuffer, without the weak reference flush. 107 : */ 108 : std::shared_ptr<RingBuffer> getRingBuffer(const std::string& id) const; 109 : 110 : bool isAudioMeterActive(const std::string& id); 111 : void setAudioMeterState(const std::string& id, bool state); 112 : 113 : private: 114 : NON_COPYABLE(RingBufferPool); 115 : 116 : // A set of RingBuffers readable by a call 117 : using ReadBindings 118 : = std::set<std::shared_ptr<RingBuffer>, std::owner_less<std::shared_ptr<RingBuffer>>>; 119 : 120 : const ReadBindings* getReadBindings(const std::string& ringbufferId) const; 121 : ReadBindings* getReadBindings(const std::string& ringbufferId); 122 : 123 : void removeReadBindings(const std::string& ringbufferId); 124 : 125 : void addReaderToRingBuffer(const std::shared_ptr<RingBuffer>& rbuf, const std::string& ringbufferId); 126 : 127 : void removeReaderFromRingBuffer(const std::shared_ptr<RingBuffer>& rbuf, 128 : const std::string& ringbufferId); 129 : 130 : // A cache of created RingBuffers listed by IDs. 131 : std::map<std::string, std::weak_ptr<RingBuffer>> ringBufferMap_ {}; 132 : 133 : // A map of which RingBuffers a call has some ReadOffsets 134 : std::map<std::string, ReadBindings> readBindingsMap_ {}; 135 : 136 : mutable std::recursive_mutex stateLock_ {}; 137 : 138 : AudioFormat internalAudioFormat_ {AudioFormat::DEFAULT()}; 139 : 140 : std::shared_ptr<RingBuffer> defaultRingBuffer_; 141 : }; 142 : 143 : } // namespace jami