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.
5 #include "media/base/decoder_buffer_queue.h"
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"
14 DecoderBufferQueue::DecoderBufferQueue()
15 : earliest_valid_timestamp_(kNoTimestamp()),
19 DecoderBufferQueue::~DecoderBufferQueue() {}
21 void DecoderBufferQueue::Push(const scoped_refptr
<DecoderBuffer
>& buffer
) {
22 CHECK(!buffer
->end_of_stream());
24 queue_
.push_back(buffer
);
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());
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";
37 if (earliest_valid_timestamp_
== kNoTimestamp()) {
38 earliest_valid_timestamp_
= buffer
->timestamp();
41 if (buffer
->timestamp() < earliest_valid_timestamp_
) {
43 << "Out of order timestamps: "
44 << buffer
->timestamp().InMicroseconds()
46 << earliest_valid_timestamp_
.InMicroseconds();
50 earliest_valid_timestamp_
= buffer
->timestamp();
51 in_order_queue_
.push_back(buffer
);
54 scoped_refptr
<DecoderBuffer
> DecoderBufferQueue::Pop() {
55 scoped_refptr
<DecoderBuffer
> buffer
= queue_
.front();
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
;
63 if (!in_order_queue_
.empty() &&
64 in_order_queue_
.front().get() == buffer
.get()) {
65 in_order_queue_
.pop_front();
71 void DecoderBufferQueue::Clear() {
74 in_order_queue_
.clear();
75 earliest_valid_timestamp_
= kNoTimestamp();
78 bool DecoderBufferQueue::IsEmpty() {
79 return queue_
.empty();
82 base::TimeDelta
DecoderBufferQueue::Duration() {
83 if (in_order_queue_
.size() < 2)
84 return base::TimeDelta();
86 base::TimeDelta start
= in_order_queue_
.front()->timestamp();
87 base::TimeDelta end
= in_order_queue_
.back()->timestamp();