Home | History | Annotate | Download | only in base
      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 
     14 DecoderBufferQueue::DecoderBufferQueue()
     15     : earliest_valid_timestamp_(kNoTimestamp()),
     16       data_size_(0) {
     17 }
     18 
     19 DecoderBufferQueue::~DecoderBufferQueue() {}
     20 
     21 void 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 
     54 scoped_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 
     71 void DecoderBufferQueue::Clear() {
     72   queue_.clear();
     73   data_size_ = 0;
     74   in_order_queue_.clear();
     75   earliest_valid_timestamp_ = kNoTimestamp();
     76 }
     77 
     78 bool DecoderBufferQueue::IsEmpty() {
     79   return queue_.empty();
     80 }
     81 
     82 base::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