1 /*
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "rtc_base/buffer_queue.h"
12
13 #include <stdint.h>
14 #include <string.h>
15
16 #include <algorithm>
17
18 namespace rtc {
19
BufferQueue(size_t capacity,size_t default_size)20 BufferQueue::BufferQueue(size_t capacity, size_t default_size)
21 : capacity_(capacity), default_size_(default_size) {}
22
~BufferQueue()23 BufferQueue::~BufferQueue() {
24 webrtc::MutexLock lock(&mutex_);
25
26 for (Buffer* buffer : queue_) {
27 delete buffer;
28 }
29 for (Buffer* buffer : free_list_) {
30 delete buffer;
31 }
32 }
33
size() const34 size_t BufferQueue::size() const {
35 webrtc::MutexLock lock(&mutex_);
36 return queue_.size();
37 }
38
Clear()39 void BufferQueue::Clear() {
40 webrtc::MutexLock lock(&mutex_);
41 while (!queue_.empty()) {
42 free_list_.push_back(queue_.front());
43 queue_.pop_front();
44 }
45 }
46
ReadFront(void * buffer,size_t bytes,size_t * bytes_read)47 bool BufferQueue::ReadFront(void* buffer, size_t bytes, size_t* bytes_read) {
48 webrtc::MutexLock lock(&mutex_);
49 if (queue_.empty()) {
50 return false;
51 }
52
53 bool was_writable = queue_.size() < capacity_;
54 Buffer* packet = queue_.front();
55 queue_.pop_front();
56
57 bytes = std::min(bytes, packet->size());
58 memcpy(buffer, packet->data(), bytes);
59 if (bytes_read) {
60 *bytes_read = bytes;
61 }
62 free_list_.push_back(packet);
63 if (!was_writable) {
64 NotifyWritableForTest();
65 }
66 return true;
67 }
68
WriteBack(const void * buffer,size_t bytes,size_t * bytes_written)69 bool BufferQueue::WriteBack(const void* buffer,
70 size_t bytes,
71 size_t* bytes_written) {
72 webrtc::MutexLock lock(&mutex_);
73 if (queue_.size() == capacity_) {
74 return false;
75 }
76
77 bool was_readable = !queue_.empty();
78 Buffer* packet;
79 if (!free_list_.empty()) {
80 packet = free_list_.back();
81 free_list_.pop_back();
82 } else {
83 packet = new Buffer(bytes, default_size_);
84 }
85
86 packet->SetData(static_cast<const uint8_t*>(buffer), bytes);
87 if (bytes_written) {
88 *bytes_written = bytes;
89 }
90 queue_.push_back(packet);
91 if (!was_readable) {
92 NotifyReadableForTest();
93 }
94 return true;
95 }
96
97 } // namespace rtc
98