| /* |
| * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "modules/video_coding/timestamp_map.h" |
| |
| #include <stdlib.h> |
| |
| #include "modules/include/module_common_types_public.h" |
| |
| namespace webrtc { |
| |
| VCMTimestampMap::VCMTimestampMap(size_t capacity) |
| : ring_buffer_(new TimestampDataTuple[capacity]), |
| capacity_(capacity), |
| next_add_idx_(0), |
| next_pop_idx_(0) {} |
| |
| VCMTimestampMap::~VCMTimestampMap() {} |
| |
| void VCMTimestampMap::Add(uint32_t timestamp, const VCMFrameInformation& data) { |
| ring_buffer_[next_add_idx_].timestamp = timestamp; |
| ring_buffer_[next_add_idx_].data = data; |
| next_add_idx_ = (next_add_idx_ + 1) % capacity_; |
| |
| if (next_add_idx_ == next_pop_idx_) { |
| // Circular list full; forget oldest entry. |
| next_pop_idx_ = (next_pop_idx_ + 1) % capacity_; |
| } |
| } |
| |
| absl::optional<VCMFrameInformation> VCMTimestampMap::Pop(uint32_t timestamp) { |
| while (!IsEmpty()) { |
| if (ring_buffer_[next_pop_idx_].timestamp == timestamp) { |
| // Found start time for this timestamp. |
| const VCMFrameInformation& data = ring_buffer_[next_pop_idx_].data; |
| ring_buffer_[next_pop_idx_].timestamp = 0; |
| next_pop_idx_ = (next_pop_idx_ + 1) % capacity_; |
| return data; |
| } else if (IsNewerTimestamp(ring_buffer_[next_pop_idx_].timestamp, |
| timestamp)) { |
| // The timestamp we are looking for is not in the list. |
| return absl::nullopt; |
| } |
| |
| // Not in this position, check next (and forget this position). |
| next_pop_idx_ = (next_pop_idx_ + 1) % capacity_; |
| } |
| |
| // Could not find matching timestamp in list. |
| return absl::nullopt; |
| } |
| |
| bool VCMTimestampMap::IsEmpty() const { |
| return (next_add_idx_ == next_pop_idx_); |
| } |
| |
| size_t VCMTimestampMap::Size() const { |
| // The maximum number of elements in the list is |capacity_| - 1. The list is |
| // empty if the add and pop indices are equal. |
| return next_add_idx_ >= next_pop_idx_ |
| ? next_add_idx_ - next_pop_idx_ |
| : next_add_idx_ + capacity_ - next_pop_idx_; |
| } |
| |
| void VCMTimestampMap::Clear() { |
| while (!IsEmpty()) { |
| ring_buffer_[next_pop_idx_].timestamp = 0; |
| next_pop_idx_ = (next_pop_idx_ + 1) % capacity_; |
| } |
| } |
| |
| } // namespace webrtc |