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 #ifndef MEDIA_BASE_DECODER_BUFFER_H_ 6 #define MEDIA_BASE_DECODER_BUFFER_H_ 7 8 #include <string> 9 #include <utility> 10 11 #include "base/logging.h" 12 #include "base/memory/aligned_memory.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "base/time/time.h" 16 #include "build/build_config.h" 17 #include "media/base/buffers.h" 18 #include "media/base/decrypt_config.h" 19 #include "media/base/media_export.h" 20 21 namespace media { 22 23 // A specialized buffer for interfacing with audio / video decoders. 24 // 25 // Specifically ensures that data is aligned and padded as necessary by the 26 // underlying decoding framework. On desktop platforms this means memory is 27 // allocated using FFmpeg with particular alignment and padding requirements. 28 // 29 // Also includes decoder specific functionality for decryption. 30 // 31 // NOTE: It is illegal to call any method when end_of_stream() is true. 32 class MEDIA_EXPORT DecoderBuffer 33 : public base::RefCountedThreadSafe<DecoderBuffer> { 34 public: 35 enum { 36 kPaddingSize = 32, 37 #if defined(ARCH_CPU_ARM_FAMILY) 38 kAlignmentSize = 16 39 #else 40 kAlignmentSize = 32 41 #endif 42 }; 43 44 // Allocates buffer with |size| >= 0. Buffer will be padded and aligned 45 // as necessary. 46 explicit DecoderBuffer(int size); 47 48 // Create a DecoderBuffer whose |data_| is copied from |data|. Buffer will be 49 // padded and aligned as necessary. |data| must not be NULL and |size| >= 0. 50 static scoped_refptr<DecoderBuffer> CopyFrom(const uint8* data, int size); 51 52 // Create a DecoderBuffer whose |data_| is copied from |data| and |side_data_| 53 // is copied from |side_data|. Buffers will be padded and aligned as necessary 54 // Data pointers must not be NULL and sizes must be >= 0. 55 static scoped_refptr<DecoderBuffer> CopyFrom(const uint8* data, int size, 56 const uint8* side_data, 57 int side_data_size); 58 59 // Create a DecoderBuffer indicating we've reached end of stream. 60 // 61 // Calling any method other than end_of_stream() on the resulting buffer 62 // is disallowed. 63 static scoped_refptr<DecoderBuffer> CreateEOSBuffer(); 64 timestamp()65 base::TimeDelta timestamp() const { 66 DCHECK(!end_of_stream()); 67 return timestamp_; 68 } 69 70 // TODO(dalecurtis): This should be renamed at some point, but to avoid a yak 71 // shave keep as a virtual with hacker_style() for now. 72 virtual void set_timestamp(base::TimeDelta timestamp); 73 duration()74 base::TimeDelta duration() const { 75 DCHECK(!end_of_stream()); 76 return duration_; 77 } 78 set_duration(base::TimeDelta duration)79 void set_duration(base::TimeDelta duration) { 80 DCHECK(!end_of_stream()); 81 DCHECK(duration == kNoTimestamp() || 82 (duration >= base::TimeDelta() && duration != kInfiniteDuration())) 83 << duration.InSecondsF(); 84 duration_ = duration; 85 } 86 data()87 const uint8* data() const { 88 DCHECK(!end_of_stream()); 89 return data_.get(); 90 } 91 writable_data()92 uint8* writable_data() const { 93 DCHECK(!end_of_stream()); 94 return data_.get(); 95 } 96 data_size()97 int data_size() const { 98 DCHECK(!end_of_stream()); 99 return size_; 100 } 101 side_data()102 const uint8* side_data() const { 103 DCHECK(!end_of_stream()); 104 return side_data_.get(); 105 } 106 side_data_size()107 int side_data_size() const { 108 DCHECK(!end_of_stream()); 109 return side_data_size_; 110 } 111 112 // A discard window indicates the amount of data which should be discard from 113 // this buffer after decoding. The first value is the amount of the front and 114 // the second the amount off the back. A value of kInfiniteDuration() for the 115 // first value indicates the entire buffer should be discarded; the second 116 // value must be base::TimeDelta() in this case. 117 typedef std::pair<base::TimeDelta, base::TimeDelta> DiscardPadding; discard_padding()118 const DiscardPadding& discard_padding() const { 119 DCHECK(!end_of_stream()); 120 return discard_padding_; 121 } 122 set_discard_padding(const DiscardPadding & discard_padding)123 void set_discard_padding(const DiscardPadding& discard_padding) { 124 DCHECK(!end_of_stream()); 125 discard_padding_ = discard_padding; 126 } 127 decrypt_config()128 const DecryptConfig* decrypt_config() const { 129 DCHECK(!end_of_stream()); 130 return decrypt_config_.get(); 131 } 132 set_decrypt_config(scoped_ptr<DecryptConfig> decrypt_config)133 void set_decrypt_config(scoped_ptr<DecryptConfig> decrypt_config) { 134 DCHECK(!end_of_stream()); 135 decrypt_config_ = decrypt_config.Pass(); 136 } 137 138 // If there's no data in this buffer, it represents end of stream. end_of_stream()139 bool end_of_stream() const { 140 return data_ == NULL; 141 } 142 143 // Indicates this buffer is part of a splice around |splice_timestamp_|. 144 // Returns kNoTimestamp() if the buffer is not part of a splice. splice_timestamp()145 base::TimeDelta splice_timestamp() const { 146 DCHECK(!end_of_stream()); 147 return splice_timestamp_; 148 } 149 150 // When set to anything but kNoTimestamp() indicates this buffer is part of a 151 // splice around |splice_timestamp|. set_splice_timestamp(base::TimeDelta splice_timestamp)152 void set_splice_timestamp(base::TimeDelta splice_timestamp) { 153 DCHECK(!end_of_stream()); 154 splice_timestamp_ = splice_timestamp; 155 } 156 157 // Returns a human-readable string describing |*this|. 158 std::string AsHumanReadableString(); 159 160 protected: 161 friend class base::RefCountedThreadSafe<DecoderBuffer>; 162 163 // Allocates a buffer of size |size| >= 0 and copies |data| into it. Buffer 164 // will be padded and aligned as necessary. If |data| is NULL then |data_| is 165 // set to NULL and |buffer_size_| to 0. 166 DecoderBuffer(const uint8* data, int size, 167 const uint8* side_data, int side_data_size); 168 virtual ~DecoderBuffer(); 169 170 private: 171 base::TimeDelta timestamp_; 172 base::TimeDelta duration_; 173 174 int size_; 175 scoped_ptr<uint8, base::AlignedFreeDeleter> data_; 176 int side_data_size_; 177 scoped_ptr<uint8, base::AlignedFreeDeleter> side_data_; 178 scoped_ptr<DecryptConfig> decrypt_config_; 179 DiscardPadding discard_padding_; 180 base::TimeDelta splice_timestamp_; 181 182 // Constructor helper method for memory allocations. 183 void Initialize(); 184 185 DISALLOW_COPY_AND_ASSIGN(DecoderBuffer); 186 }; 187 188 } // namespace media 189 190 #endif // MEDIA_BASE_DECODER_BUFFER_H_ 191