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_STREAM_PARSER_BUFFER_H_ 6 #define MEDIA_BASE_STREAM_PARSER_BUFFER_H_ 7 8 #include <deque> 9 10 #include "media/base/decoder_buffer.h" 11 #include "media/base/demuxer_stream.h" 12 #include "media/base/media_export.h" 13 #include "media/base/stream_parser.h" 14 15 namespace media { 16 17 // Simple wrapper around base::TimeDelta that represents a decode timestamp. 18 // Making DecodeTimestamp a different type makes it easier to determine whether 19 // code is operating on presentation or decode timestamps and makes conversions 20 // between the two types explicit and easy to spot. 21 class DecodeTimestamp { 22 public: 23 DecodeTimestamp() {} 24 DecodeTimestamp(const DecodeTimestamp& rhs) : ts_(rhs.ts_) { } 25 DecodeTimestamp& operator=(const DecodeTimestamp& rhs) { 26 if (&rhs != this) 27 ts_ = rhs.ts_; 28 return *this; 29 } 30 31 // Only operators that are actually used by the code have been defined. 32 // Reviewers should pay close attention to the addition of new operators. 33 bool operator<(const DecodeTimestamp& rhs) const { return ts_ < rhs.ts_; } 34 bool operator>(const DecodeTimestamp& rhs) const { return ts_ > rhs.ts_; } 35 bool operator==(const DecodeTimestamp& rhs) const { return ts_ == rhs.ts_; } 36 bool operator!=(const DecodeTimestamp& rhs) const { return ts_ != rhs.ts_; } 37 bool operator>=(const DecodeTimestamp& rhs) const { return ts_ >= rhs.ts_; } 38 bool operator<=(const DecodeTimestamp& rhs) const { return ts_ <= rhs.ts_; } 39 40 base::TimeDelta operator-(const DecodeTimestamp& rhs) const { 41 return ts_ - rhs.ts_; 42 } 43 44 DecodeTimestamp& operator+=(const base::TimeDelta& rhs) { 45 ts_ += rhs; 46 return *this; 47 } 48 49 DecodeTimestamp& operator-=(const base::TimeDelta& rhs) { 50 ts_ -= rhs; 51 return *this; 52 } 53 54 DecodeTimestamp operator+(const base::TimeDelta& rhs) const { 55 return DecodeTimestamp(ts_ + rhs); 56 } 57 58 DecodeTimestamp operator-(const base::TimeDelta& rhs) const { 59 return DecodeTimestamp(ts_ - rhs); 60 } 61 62 int64 operator/(const base::TimeDelta& rhs) const { 63 return ts_ / rhs; 64 } 65 66 static DecodeTimestamp FromSecondsD(double seconds) { 67 return DecodeTimestamp(base::TimeDelta::FromSecondsD(seconds)); 68 } 69 70 static DecodeTimestamp FromMilliseconds(int64 milliseconds) { 71 return DecodeTimestamp(base::TimeDelta::FromMilliseconds(milliseconds)); 72 } 73 74 static DecodeTimestamp FromMicroseconds(int64 microseconds) { 75 return DecodeTimestamp(base::TimeDelta::FromMicroseconds(microseconds)); 76 } 77 78 // This method is used to explicitly call out when presentation timestamps 79 // are being converted to a decode timestamp. 80 static DecodeTimestamp FromPresentationTime(base::TimeDelta timestamp) { 81 return DecodeTimestamp(timestamp); 82 } 83 84 double InSecondsF() const { return ts_.InSecondsF(); } 85 int64 InMilliseconds() const { return ts_.InMilliseconds(); } 86 int64 InMicroseconds() const { return ts_.InMicroseconds(); } 87 88 // TODO(acolwell): Remove once all the hacks are gone. This method is called 89 // by hacks where a decode time is being used as a presentation time. 90 base::TimeDelta ToPresentationTime() const { return ts_; } 91 92 private: 93 explicit DecodeTimestamp(base::TimeDelta timestamp) : ts_(timestamp) { } 94 95 base::TimeDelta ts_; 96 }; 97 98 MEDIA_EXPORT extern inline DecodeTimestamp kNoDecodeTimestamp() { 99 return DecodeTimestamp::FromPresentationTime(kNoTimestamp()); 100 } 101 102 class MEDIA_EXPORT StreamParserBuffer : public DecoderBuffer { 103 public: 104 // Value used to signal an invalid decoder config ID. 105 enum { kInvalidConfigId = -1 }; 106 107 typedef DemuxerStream::Type Type; 108 typedef StreamParser::TrackId TrackId; 109 110 static scoped_refptr<StreamParserBuffer> CreateEOSBuffer(); 111 112 static scoped_refptr<StreamParserBuffer> CopyFrom( 113 const uint8* data, int data_size, bool is_keyframe, Type type, 114 TrackId track_id); 115 static scoped_refptr<StreamParserBuffer> CopyFrom( 116 const uint8* data, int data_size, 117 const uint8* side_data, int side_data_size, bool is_keyframe, Type type, 118 TrackId track_id); 119 bool IsKeyframe() const { return is_keyframe_; } 120 121 // Decode timestamp. If not explicitly set, or set to kNoTimestamp(), the 122 // value will be taken from the normal timestamp. 123 DecodeTimestamp GetDecodeTimestamp() const; 124 void SetDecodeTimestamp(DecodeTimestamp timestamp); 125 126 // Gets/sets the ID of the decoder config associated with this buffer. 127 int GetConfigId() const; 128 void SetConfigId(int config_id); 129 130 // Returns the config ID of this buffer if it has no splice buffers or 131 // |index| is out of range. Otherwise returns the config ID for the 132 // buffer in |splice_buffers_| at position |index|. 133 int GetSpliceBufferConfigId(size_t index) const; 134 135 // Gets the parser's media type associated with this buffer. Value is 136 // meaningless for EOS buffers. 137 Type type() const { return type_; } 138 139 // Gets the parser's track ID associated with this buffer. Value is 140 // meaningless for EOS buffers. 141 TrackId track_id() const { return track_id_; } 142 143 // Converts this buffer to a splice buffer. |pre_splice_buffers| must not 144 // have any EOS buffers, must not have any splice buffers, nor must have any 145 // buffer with preroll. 146 // 147 // |pre_splice_buffers| will be deep copied and each copy's splice_timestamp() 148 // will be set to this buffer's splice_timestamp(). A copy of |this|, with a 149 // splice_timestamp() of kNoTimestamp(), will be added to the end of 150 // |splice_buffers_|. 151 // 152 // See the Audio Splice Frame Algorithm in the MSE specification for details. 153 typedef StreamParser::BufferQueue BufferQueue; 154 void ConvertToSpliceBuffer(const BufferQueue& pre_splice_buffers); 155 const BufferQueue& splice_buffers() const { return splice_buffers_; } 156 157 // Specifies a buffer which must be decoded prior to this one to ensure this 158 // buffer can be accurately decoded. The given buffer must be of the same 159 // type, must not be a splice buffer, must not have any discard padding, and 160 // must not be an end of stream buffer. |preroll| is not copied. 161 // 162 // It's expected that this preroll buffer will be discarded entirely post 163 // decoding. As such it's discard_padding() will be set to kInfiniteDuration. 164 // 165 // All future timestamp, decode timestamp, config id, or track id changes to 166 // this buffer will be applied to the preroll buffer as well. 167 void SetPrerollBuffer(const scoped_refptr<StreamParserBuffer>& preroll); 168 const scoped_refptr<StreamParserBuffer>& preroll_buffer() { 169 return preroll_buffer_; 170 } 171 172 virtual void set_timestamp(base::TimeDelta timestamp) OVERRIDE; 173 174 private: 175 StreamParserBuffer(const uint8* data, int data_size, 176 const uint8* side_data, int side_data_size, 177 bool is_keyframe, Type type, 178 TrackId track_id); 179 virtual ~StreamParserBuffer(); 180 181 bool is_keyframe_; 182 DecodeTimestamp decode_timestamp_; 183 int config_id_; 184 Type type_; 185 TrackId track_id_; 186 BufferQueue splice_buffers_; 187 scoped_refptr<StreamParserBuffer> preroll_buffer_; 188 189 DISALLOW_COPY_AND_ASSIGN(StreamParserBuffer); 190 }; 191 192 } // namespace media 193 194 #endif // MEDIA_BASE_STREAM_PARSER_BUFFER_H_ 195