12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/decoder_buffer_queue.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/numerics/safe_conversions.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/buffers.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/decoder_buffer.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media {
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DecoderBufferQueue::DecoderBufferQueue()
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : earliest_valid_timestamp_(kNoTimestamp()),
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      data_size_(0) {
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DecoderBufferQueue::~DecoderBufferQueue() {}
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DecoderBufferQueue::Push(const scoped_refptr<DecoderBuffer>& buffer) {
22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CHECK(!buffer->end_of_stream());
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  queue_.push_back(buffer);
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(damienv): Remove the cast here and in every place in this file
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // when DecoderBuffer::data_size is modified to return a size_t.
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  data_size_ += base::checked_cast<size_t, int>(buffer->data_size());
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(scherkus): FFmpeg returns some packets with no timestamp after
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // seeking. Fix and turn this into CHECK(). See http://crbug.com/162192
32ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (buffer->timestamp() == kNoTimestamp()) {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DVLOG(1) << "Buffer has no timestamp";
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (earliest_valid_timestamp_ == kNoTimestamp()) {
38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    earliest_valid_timestamp_ = buffer->timestamp();
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (buffer->timestamp() < earliest_valid_timestamp_) {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DVLOG(1)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Out of order timestamps: "
44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        << buffer->timestamp().InMicroseconds()
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << " vs. "
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << earliest_valid_timestamp_.InMicroseconds();
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  earliest_valid_timestamp_ = buffer->timestamp();
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_order_queue_.push_back(buffer);
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<DecoderBuffer> DecoderBufferQueue::Pop() {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<DecoderBuffer> buffer = queue_.front();
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  queue_.pop_front();
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  size_t buffer_data_size =
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::checked_cast<size_t, int>(buffer->data_size());
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_LE(buffer_data_size, data_size_);
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  data_size_ -= buffer_data_size;
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!in_order_queue_.empty() &&
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      in_order_queue_.front().get() == buffer.get()) {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    in_order_queue_.pop_front();
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return buffer;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DecoderBufferQueue::Clear() {
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  queue_.clear();
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  data_size_ = 0;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_order_queue_.clear();
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  earliest_valid_timestamp_ = kNoTimestamp();
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DecoderBufferQueue::IsEmpty() {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return queue_.empty();
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::TimeDelta DecoderBufferQueue::Duration() {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (in_order_queue_.size() < 2)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::TimeDelta();
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::TimeDelta start = in_order_queue_.front()->timestamp();
87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::TimeDelta end = in_order_queue_.back()->timestamp();
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return end - start;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace media
92