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