15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MEDIA_BASE_DECODER_BUFFER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_BASE_DECODER_BUFFER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <utility>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/logging.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/aligned_memory.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/base/buffers.h"
18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "media/base/decrypt_config.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/media_export.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A specialized buffer for interfacing with audio / video decoders.
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Specifically ensures that data is aligned and padded as necessary by the
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// underlying decoding framework.  On desktop platforms this means memory is
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// allocated using FFmpeg with particular alignment and padding requirements.
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Also includes decoder specific functionality for decryption.
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// NOTE: It is illegal to call any method when end_of_stream() is true.
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MEDIA_EXPORT DecoderBuffer
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public base::RefCountedThreadSafe<DecoderBuffer> {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum {
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    kPaddingSize = 32,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ARCH_CPU_ARM_FAMILY)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kAlignmentSize = 16
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kAlignmentSize = 32
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Allocates buffer with |size| >= 0.  Buffer will be padded and aligned
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // as necessary.
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit DecoderBuffer(int size);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a DecoderBuffer whose |data_| is copied from |data|.  Buffer will be
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // padded and aligned as necessary.  |data| must not be NULL and |size| >= 0.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static scoped_refptr<DecoderBuffer> CopyFrom(const uint8* data, int size);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a DecoderBuffer whose |data_| is copied from |data| and |side_data_|
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is copied from |side_data|. Buffers will be padded and aligned as necessary
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Data pointers must not be NULL and sizes must be >= 0.
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static scoped_refptr<DecoderBuffer> CopyFrom(const uint8* data, int size,
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                               const uint8* side_data,
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                               int side_data_size);
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a DecoderBuffer indicating we've reached end of stream.
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Calling any method other than end_of_stream() on the resulting buffer
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is disallowed.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static scoped_refptr<DecoderBuffer> CreateEOSBuffer();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::TimeDelta timestamp() const {
66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DCHECK(!end_of_stream());
67ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return timestamp_;
68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // TODO(dalecurtis): This should be renamed at some point, but to avoid a yak
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // shave keep as a virtual with hacker_style() for now.
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void set_timestamp(base::TimeDelta timestamp);
73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::TimeDelta duration() const {
75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DCHECK(!end_of_stream());
76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return duration_;
77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void set_duration(base::TimeDelta duration) {
80ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DCHECK(!end_of_stream());
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK(duration == kNoTimestamp() ||
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           (duration >= base::TimeDelta() && duration != kInfiniteDuration()))
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        << duration.InSecondsF();
84ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    duration_ = duration;
85ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  const uint8* data() const {
88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DCHECK(!end_of_stream());
89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return data_.get();
90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
91ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
92ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  uint8* writable_data() const {
93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DCHECK(!end_of_stream());
94ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return data_.get();
95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int data_size() const {
98ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DCHECK(!end_of_stream());
99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return size_;
100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  const uint8* side_data() const {
103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DCHECK(!end_of_stream());
104ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return side_data_.get();
105ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
106ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
107ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int side_data_size() const {
108ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DCHECK(!end_of_stream());
109ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return side_data_size_;
110ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
111ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // A discard window indicates the amount of data which should be discard from
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // this buffer after decoding.  The first value is the amount of the front and
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the second the amount off the back.  A value of kInfiniteDuration() for the
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // first value indicates the entire buffer should be discarded; the second
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // value must be base::TimeDelta() in this case.
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  typedef std::pair<base::TimeDelta, base::TimeDelta> DiscardPadding;
118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const DiscardPadding& discard_padding() const {
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(!end_of_stream());
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return discard_padding_;
12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void set_discard_padding(const DiscardPadding& discard_padding) {
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(!end_of_stream());
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    discard_padding_ = discard_padding;
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
128ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  const DecryptConfig* decrypt_config() const {
129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DCHECK(!end_of_stream());
130ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return decrypt_config_.get();
131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void set_decrypt_config(scoped_ptr<DecryptConfig> decrypt_config) {
134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DCHECK(!end_of_stream());
135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    decrypt_config_ = decrypt_config.Pass();
136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there's no data in this buffer, it represents end of stream.
139ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  bool end_of_stream() const {
140ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return data_ == NULL;
141ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Indicates this buffer is part of a splice around |splice_timestamp_|.
144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Returns kNoTimestamp() if the buffer is not part of a splice.
145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::TimeDelta splice_timestamp() const {
146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK(!end_of_stream());
147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return splice_timestamp_;
148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // When set to anything but kNoTimestamp() indicates this buffer is part of a
151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // splice around |splice_timestamp|.
152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void set_splice_timestamp(base::TimeDelta splice_timestamp) {
153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK(!end_of_stream());
154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    splice_timestamp_ = splice_timestamp;
155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns a human-readable string describing |*this|.
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string AsHumanReadableString();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class base::RefCountedThreadSafe<DecoderBuffer>;
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allocates a buffer of size |size| >= 0 and copies |data| into it.  Buffer
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be padded and aligned as necessary.  If |data| is NULL then |data_| is
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // set to NULL and |buffer_size_| to 0.
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DecoderBuffer(const uint8* data, int size,
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                const uint8* side_data, int side_data_size);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DecoderBuffer();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta timestamp_;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta duration_;
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int size_;
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<uint8, base::AlignedFreeDeleter> data_;
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int side_data_size_;
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<uint8, base::AlignedFreeDeleter> side_data_;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DecryptConfig> decrypt_config_;
179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DiscardPadding discard_padding_;
180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::TimeDelta splice_timestamp_;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constructor helper method for memory allocations.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Initialize();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DecoderBuffer);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // MEDIA_BASE_DECODER_BUFFER_H_
191