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