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 RTC_DCHECK_RUN_ON(&sequence_checker_);
25 for (Buffer* buffer : queue_)
26 delete buffer;
27 for (Buffer* buffer : free_list_)
28 delete buffer;
29 }
30
size() const31 size_t BufferQueue::size() const {
32 RTC_DCHECK_RUN_ON(&sequence_checker_);
33 return queue_.size();
34 }
35
Clear()36 void BufferQueue::Clear() {
37 RTC_DCHECK_RUN_ON(&sequence_checker_);
38 while (!queue_.empty()) {
39 free_list_.push_back(queue_.front());
40 queue_.pop_front();
41 }
42 }
43
ReadFront(void * buffer,size_t bytes,size_t * bytes_read)44 bool BufferQueue::ReadFront(void* buffer, size_t bytes, size_t* bytes_read) {
45 RTC_DCHECK_RUN_ON(&sequence_checker_);
46 if (queue_.empty())
47 return false;
48
49 Buffer* packet = queue_.front();
50 queue_.pop_front();
51
52 bytes = std::min(bytes, packet->size());
53 memcpy(buffer, packet->data(), bytes);
54
55 if (bytes_read)
56 *bytes_read = bytes;
57
58 free_list_.push_back(packet);
59 return true;
60 }
61
WriteBack(const void * buffer,size_t bytes,size_t * bytes_written)62 bool BufferQueue::WriteBack(const void* buffer,
63 size_t bytes,
64 size_t* bytes_written) {
65 RTC_DCHECK_RUN_ON(&sequence_checker_);
66 if (queue_.size() == capacity_)
67 return false;
68
69 Buffer* packet;
70 if (!free_list_.empty()) {
71 packet = free_list_.back();
72 free_list_.pop_back();
73 } else {
74 packet = new Buffer(bytes, default_size_);
75 }
76
77 packet->SetData(static_cast<const uint8_t*>(buffer), bytes);
78 if (bytes_written)
79 *bytes_written = bytes;
80
81 queue_.push_back(packet);
82 return true;
83 }
84
85 } // namespace rtc
86