1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "media/base/decoder_buffer_queue.h" 6 7 #include "base/logging.h" 8 #include "base/numerics/safe_conversions.h" 9 #include "media/base/buffers.h" 10 #include "media/base/decoder_buffer.h" 11 12 namespace media { 13 DecoderBufferQueue()14DecoderBufferQueue::DecoderBufferQueue() 15 : earliest_valid_timestamp_(kNoTimestamp()), 16 data_size_(0) { 17 } 18 ~DecoderBufferQueue()19DecoderBufferQueue::~DecoderBufferQueue() {} 20 Push(const scoped_refptr<DecoderBuffer> & buffer)21void DecoderBufferQueue::Push(const scoped_refptr<DecoderBuffer>& buffer) { 22 CHECK(!buffer->end_of_stream()); 23 24 queue_.push_back(buffer); 25 26 // TODO(damienv): Remove the cast here and in every place in this file 27 // when DecoderBuffer::data_size is modified to return a size_t. 28 data_size_ += base::checked_cast<size_t, int>(buffer->data_size()); 29 30 // TODO(scherkus): FFmpeg returns some packets with no timestamp after 31 // seeking. Fix and turn this into CHECK(). See http://crbug.com/162192 32 if (buffer->timestamp() == kNoTimestamp()) { 33 DVLOG(1) << "Buffer has no timestamp"; 34 return; 35 } 36 37 if (earliest_valid_timestamp_ == kNoTimestamp()) { 38 earliest_valid_timestamp_ = buffer->timestamp(); 39 } 40 41 if (buffer->timestamp() < earliest_valid_timestamp_) { 42 DVLOG(1) 43 << "Out of order timestamps: " 44 << buffer->timestamp().InMicroseconds() 45 << " vs. " 46 << earliest_valid_timestamp_.InMicroseconds(); 47 return; 48 } 49 50 earliest_valid_timestamp_ = buffer->timestamp(); 51 in_order_queue_.push_back(buffer); 52 } 53 Pop()54scoped_refptr<DecoderBuffer> DecoderBufferQueue::Pop() { 55 scoped_refptr<DecoderBuffer> buffer = queue_.front(); 56 queue_.pop_front(); 57 58 size_t buffer_data_size = 59 base::checked_cast<size_t, int>(buffer->data_size()); 60 DCHECK_LE(buffer_data_size, data_size_); 61 data_size_ -= buffer_data_size; 62 63 if (!in_order_queue_.empty() && 64 in_order_queue_.front().get() == buffer.get()) { 65 in_order_queue_.pop_front(); 66 } 67 68 return buffer; 69 } 70 Clear()71void DecoderBufferQueue::Clear() { 72 queue_.clear(); 73 data_size_ = 0; 74 in_order_queue_.clear(); 75 earliest_valid_timestamp_ = kNoTimestamp(); 76 } 77 IsEmpty()78bool DecoderBufferQueue::IsEmpty() { 79 return queue_.empty(); 80 } 81 Duration()82base::TimeDelta DecoderBufferQueue::Duration() { 83 if (in_order_queue_.size() < 2) 84 return base::TimeDelta(); 85 86 base::TimeDelta start = in_order_queue_.front()->timestamp(); 87 base::TimeDelta end = in_order_queue_.back()->timestamp(); 88 return end - start; 89 } 90 91 } // namespace media 92