Temporarily re-enabling SizeAfterPrefChange test with traces (this time for Linux...
[chromium-blink-merge.git] / media / base / stream_parser_buffer.cc
blobe9d64272c4d84670c4b2e7e1fe739433e856412b
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.
5 #include "media/base/stream_parser_buffer.h"
7 #include "base/logging.h"
8 #include "media/base/buffers.h"
10 namespace media {
12 static scoped_refptr<StreamParserBuffer> CopyBuffer(
13 const StreamParserBuffer& buffer) {
14 if (buffer.end_of_stream())
15 return StreamParserBuffer::CreateEOSBuffer();
17 scoped_refptr<StreamParserBuffer> copied_buffer =
18 StreamParserBuffer::CopyFrom(buffer.data(),
19 buffer.data_size(),
20 buffer.side_data(),
21 buffer.side_data_size(),
22 buffer.IsKeyframe(),
23 buffer.type(),
24 buffer.track_id());
25 copied_buffer->SetDecodeTimestamp(buffer.GetDecodeTimestamp());
26 copied_buffer->SetConfigId(buffer.GetConfigId());
27 copied_buffer->set_timestamp(buffer.timestamp());
28 copied_buffer->set_duration(buffer.duration());
29 copied_buffer->set_discard_padding(buffer.discard_padding());
30 copied_buffer->set_splice_timestamp(buffer.splice_timestamp());
31 const DecryptConfig* decrypt_config = buffer.decrypt_config();
32 if (decrypt_config) {
33 copied_buffer->set_decrypt_config(
34 make_scoped_ptr(new DecryptConfig(decrypt_config->key_id(),
35 decrypt_config->iv(),
36 decrypt_config->subsamples())));
39 return copied_buffer;
42 scoped_refptr<StreamParserBuffer> StreamParserBuffer::CreateEOSBuffer() {
43 return make_scoped_refptr(new StreamParserBuffer(NULL, 0, NULL, 0, false,
44 DemuxerStream::UNKNOWN, 0));
47 scoped_refptr<StreamParserBuffer> StreamParserBuffer::CopyFrom(
48 const uint8* data, int data_size, bool is_keyframe, Type type,
49 TrackId track_id) {
50 return make_scoped_refptr(
51 new StreamParserBuffer(data, data_size, NULL, 0, is_keyframe, type,
52 track_id));
55 scoped_refptr<StreamParserBuffer> StreamParserBuffer::CopyFrom(
56 const uint8* data, int data_size,
57 const uint8* side_data, int side_data_size,
58 bool is_keyframe, Type type, TrackId track_id) {
59 return make_scoped_refptr(
60 new StreamParserBuffer(data, data_size, side_data, side_data_size,
61 is_keyframe, type, track_id));
64 base::TimeDelta StreamParserBuffer::GetDecodeTimestamp() const {
65 if (decode_timestamp_ == kNoTimestamp())
66 return timestamp();
67 return decode_timestamp_;
70 void StreamParserBuffer::SetDecodeTimestamp(base::TimeDelta timestamp) {
71 decode_timestamp_ = timestamp;
72 if (preroll_buffer_)
73 preroll_buffer_->SetDecodeTimestamp(timestamp);
76 StreamParserBuffer::StreamParserBuffer(const uint8* data, int data_size,
77 const uint8* side_data,
78 int side_data_size, bool is_keyframe,
79 Type type, TrackId track_id)
80 : DecoderBuffer(data, data_size, side_data, side_data_size),
81 is_keyframe_(is_keyframe),
82 decode_timestamp_(kNoTimestamp()),
83 config_id_(kInvalidConfigId),
84 type_(type),
85 track_id_(track_id) {
86 // TODO(scherkus): Should DataBuffer constructor accept a timestamp and
87 // duration to force clients to set them? Today they end up being zero which
88 // is both a common and valid value and could lead to bugs.
89 if (data) {
90 set_duration(kNoTimestamp());
94 StreamParserBuffer::~StreamParserBuffer() {}
96 int StreamParserBuffer::GetConfigId() const {
97 return config_id_;
100 void StreamParserBuffer::SetConfigId(int config_id) {
101 config_id_ = config_id;
102 if (preroll_buffer_)
103 preroll_buffer_->SetConfigId(config_id);
106 void StreamParserBuffer::ConvertToSpliceBuffer(
107 const BufferQueue& pre_splice_buffers) {
108 DCHECK(splice_buffers_.empty());
109 DCHECK(!end_of_stream());
111 // Make a copy of this first, before making any changes.
112 scoped_refptr<StreamParserBuffer> overlapping_buffer = CopyBuffer(*this);
113 overlapping_buffer->set_splice_timestamp(kNoTimestamp());
115 const scoped_refptr<StreamParserBuffer>& first_splice_buffer =
116 pre_splice_buffers.front();
118 // Ensure the given buffers are actually before the splice point.
119 DCHECK(first_splice_buffer->timestamp() <= overlapping_buffer->timestamp());
121 // TODO(dalecurtis): We should also clear |data| and |side_data|, but since
122 // that implies EOS care must be taken to ensure there are no clients relying
123 // on that behavior.
125 // Move over any preroll from this buffer.
126 if (preroll_buffer_) {
127 DCHECK(!overlapping_buffer->preroll_buffer_);
128 overlapping_buffer->preroll_buffer_.swap(preroll_buffer_);
131 // Rewrite |this| buffer as a splice buffer.
132 SetDecodeTimestamp(first_splice_buffer->GetDecodeTimestamp());
133 SetConfigId(first_splice_buffer->GetConfigId());
134 set_timestamp(first_splice_buffer->timestamp());
135 is_keyframe_ = first_splice_buffer->IsKeyframe();
136 type_ = first_splice_buffer->type();
137 track_id_ = first_splice_buffer->track_id();
138 set_splice_timestamp(overlapping_buffer->timestamp());
140 // The splice duration is the duration of all buffers before the splice plus
141 // the highest ending timestamp after the splice point.
142 set_duration(
143 std::max(overlapping_buffer->timestamp() + overlapping_buffer->duration(),
144 pre_splice_buffers.back()->timestamp() +
145 pre_splice_buffers.back()->duration()) -
146 first_splice_buffer->timestamp());
148 // Copy all pre splice buffers into our wrapper buffer.
149 for (BufferQueue::const_iterator it = pre_splice_buffers.begin();
150 it != pre_splice_buffers.end();
151 ++it) {
152 const scoped_refptr<StreamParserBuffer>& buffer = *it;
153 DCHECK(!buffer->end_of_stream());
154 DCHECK(!buffer->preroll_buffer());
155 DCHECK(buffer->splice_buffers().empty());
156 splice_buffers_.push_back(CopyBuffer(*buffer));
157 splice_buffers_.back()->set_splice_timestamp(splice_timestamp());
160 splice_buffers_.push_back(overlapping_buffer);
163 void StreamParserBuffer::SetPrerollBuffer(
164 const scoped_refptr<StreamParserBuffer>& preroll_buffer) {
165 DCHECK(!preroll_buffer_);
166 DCHECK(!end_of_stream());
167 DCHECK(!preroll_buffer->end_of_stream());
168 DCHECK(!preroll_buffer->preroll_buffer_);
169 DCHECK(preroll_buffer->splice_timestamp() == kNoTimestamp());
170 DCHECK(preroll_buffer->splice_buffers().empty());
171 DCHECK(preroll_buffer->timestamp() <= timestamp());
172 DCHECK(preroll_buffer->discard_padding() == DecoderBuffer::DiscardPadding());
173 DCHECK_EQ(preroll_buffer->type(), type());
174 DCHECK_EQ(preroll_buffer->track_id(), track_id());
176 preroll_buffer_ = preroll_buffer;
177 preroll_buffer_->set_timestamp(timestamp());
178 preroll_buffer_->SetDecodeTimestamp(GetDecodeTimestamp());
180 // Mark the entire buffer for discard.
181 preroll_buffer_->set_discard_padding(
182 std::make_pair(kInfiniteDuration(), base::TimeDelta()));
185 void StreamParserBuffer::set_timestamp(base::TimeDelta timestamp) {
186 DecoderBuffer::set_timestamp(timestamp);
187 if (preroll_buffer_)
188 preroll_buffer_->set_timestamp(timestamp);
191 } // namespace media