blob: 445045ceea008e27bf1a605af83ff7cc64e6d78a [file] [log] [blame]
Joachim Bauch6f2ef742015-05-21 17:52:01 +02001/*
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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "rtc_base/buffer_queue.h"
Joachim Bauch6f2ef742015-05-21 17:52:01 +020012
Yves Gerey988cc082018-10-23 12:03:01 +020013#include <stdint.h>
14#include <string.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020015
ossub01c7812016-02-24 01:05:56 -080016#include <algorithm>
17
Joachim Bauch6f2ef742015-05-21 17:52:01 +020018namespace rtc {
19
20BufferQueue::BufferQueue(size_t capacity, size_t default_size)
Yves Gerey665174f2018-06-19 15:03:05 +020021 : capacity_(capacity), default_size_(default_size) {}
Joachim Bauch6f2ef742015-05-21 17:52:01 +020022
23BufferQueue::~BufferQueue() {
24 CritScope cs(&crit_);
25
26 for (Buffer* buffer : queue_) {
27 delete buffer;
28 }
29 for (Buffer* buffer : free_list_) {
30 delete buffer;
31 }
32}
33
34size_t BufferQueue::size() const {
35 CritScope cs(&crit_);
36 return queue_.size();
37}
38
guoweis4cc9f982016-02-24 11:10:06 -080039void BufferQueue::Clear() {
40 CritScope cs(&crit_);
41 while (!queue_.empty()) {
42 free_list_.push_back(queue_.front());
43 queue_.pop_front();
44 }
45}
46
Joachim Bauch6f2ef742015-05-21 17:52:01 +020047bool BufferQueue::ReadFront(void* buffer, size_t bytes, size_t* bytes_read) {
48 CritScope cs(&crit_);
49 if (queue_.empty()) {
50 return false;
51 }
52
jbauche488a0d2015-11-19 05:17:58 -080053 bool was_writable = queue_.size() < capacity_;
Joachim Bauch6f2ef742015-05-21 17:52:01 +020054 Buffer* packet = queue_.front();
55 queue_.pop_front();
56
jbauche488a0d2015-11-19 05:17:58 -080057 bytes = std::min(bytes, packet->size());
Joachim Bauch6f2ef742015-05-21 17:52:01 +020058 memcpy(buffer, packet->data(), bytes);
59 if (bytes_read) {
60 *bytes_read = bytes;
61 }
62 free_list_.push_back(packet);
jbauche488a0d2015-11-19 05:17:58 -080063 if (!was_writable) {
64 NotifyWritableForTest();
65 }
Joachim Bauch6f2ef742015-05-21 17:52:01 +020066 return true;
67}
68
Yves Gerey665174f2018-06-19 15:03:05 +020069bool BufferQueue::WriteBack(const void* buffer,
70 size_t bytes,
Joachim Bauch6f2ef742015-05-21 17:52:01 +020071 size_t* bytes_written) {
72 CritScope cs(&crit_);
73 if (queue_.size() == capacity_) {
74 return false;
75 }
76
jbauche488a0d2015-11-19 05:17:58 -080077 bool was_readable = !queue_.empty();
Joachim Bauch6f2ef742015-05-21 17:52:01 +020078 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);
jbauche488a0d2015-11-19 05:17:58 -080091 if (!was_readable) {
92 NotifyReadableForTest();
93 }
Joachim Bauch6f2ef742015-05-21 17:52:01 +020094 return true;
95}
96
97} // namespace rtc