Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: media/base/stream_parser_buffer.cc

Issue 276573002: Add gapless playback support for AAC playback. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix msvc error. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/base/stream_parser_buffer.h ('k') | media/filters/chunk_demuxer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/stream_parser_buffer.h" 5 #include "media/base/stream_parser_buffer.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "media/base/buffers.h" 8 #include "media/base/buffers.h"
9 9
10 namespace media { 10 namespace media {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 new StreamParserBuffer(data, data_size, side_data, side_data_size, 60 new StreamParserBuffer(data, data_size, side_data, side_data_size,
61 is_keyframe, type, track_id)); 61 is_keyframe, type, track_id));
62 } 62 }
63 63
64 base::TimeDelta StreamParserBuffer::GetDecodeTimestamp() const { 64 base::TimeDelta StreamParserBuffer::GetDecodeTimestamp() const {
65 if (decode_timestamp_ == kNoTimestamp()) 65 if (decode_timestamp_ == kNoTimestamp())
66 return timestamp(); 66 return timestamp();
67 return decode_timestamp_; 67 return decode_timestamp_;
68 } 68 }
69 69
70 void StreamParserBuffer::SetDecodeTimestamp(const base::TimeDelta& timestamp) { 70 void StreamParserBuffer::SetDecodeTimestamp(base::TimeDelta timestamp) {
71 decode_timestamp_ = timestamp; 71 decode_timestamp_ = timestamp;
72 if (preroll_buffer_)
73 preroll_buffer_->SetDecodeTimestamp(timestamp);
72 } 74 }
73 75
74 StreamParserBuffer::StreamParserBuffer(const uint8* data, int data_size, 76 StreamParserBuffer::StreamParserBuffer(const uint8* data, int data_size,
75 const uint8* side_data, 77 const uint8* side_data,
76 int side_data_size, bool is_keyframe, 78 int side_data_size, bool is_keyframe,
77 Type type, TrackId track_id) 79 Type type, TrackId track_id)
78 : DecoderBuffer(data, data_size, side_data, side_data_size), 80 : DecoderBuffer(data, data_size, side_data, side_data_size),
79 is_keyframe_(is_keyframe), 81 is_keyframe_(is_keyframe),
80 decode_timestamp_(kNoTimestamp()), 82 decode_timestamp_(kNoTimestamp()),
81 config_id_(kInvalidConfigId), 83 config_id_(kInvalidConfigId),
82 type_(type), 84 type_(type),
83 track_id_(track_id) { 85 track_id_(track_id) {
84 // TODO(scherkus): Should DataBuffer constructor accept a timestamp and 86 // TODO(scherkus): Should DataBuffer constructor accept a timestamp and
85 // duration to force clients to set them? Today they end up being zero which 87 // duration to force clients to set them? Today they end up being zero which
86 // is both a common and valid value and could lead to bugs. 88 // is both a common and valid value and could lead to bugs.
87 if (data) { 89 if (data) {
88 set_duration(kNoTimestamp()); 90 set_duration(kNoTimestamp());
89 } 91 }
90 } 92 }
91 93
92 StreamParserBuffer::~StreamParserBuffer() {} 94 StreamParserBuffer::~StreamParserBuffer() {}
93 95
94 int StreamParserBuffer::GetConfigId() const { 96 int StreamParserBuffer::GetConfigId() const {
95 return config_id_; 97 return config_id_;
96 } 98 }
97 99
98 void StreamParserBuffer::SetConfigId(int config_id) { 100 void StreamParserBuffer::SetConfigId(int config_id) {
99 config_id_ = config_id; 101 config_id_ = config_id;
102 if (preroll_buffer_)
103 preroll_buffer_->SetConfigId(config_id);
100 } 104 }
101 105
102 void StreamParserBuffer::ConvertToSpliceBuffer( 106 void StreamParserBuffer::ConvertToSpliceBuffer(
103 const BufferQueue& pre_splice_buffers) { 107 const BufferQueue& pre_splice_buffers) {
104 DCHECK(splice_buffers_.empty()); 108 DCHECK(splice_buffers_.empty());
105 DCHECK(!end_of_stream()); 109 DCHECK(!end_of_stream());
106 110
107 // Make a copy of this first, before making any changes. 111 // Make a copy of this first, before making any changes.
108 scoped_refptr<StreamParserBuffer> overlapping_buffer = CopyBuffer(*this); 112 scoped_refptr<StreamParserBuffer> overlapping_buffer = CopyBuffer(*this);
109 overlapping_buffer->set_splice_timestamp(kNoTimestamp()); 113 overlapping_buffer->set_splice_timestamp(kNoTimestamp());
110 114
111 const scoped_refptr<StreamParserBuffer>& first_splice_buffer = 115 const scoped_refptr<StreamParserBuffer>& first_splice_buffer =
112 pre_splice_buffers.front(); 116 pre_splice_buffers.front();
113 117
114 // Ensure the given buffers are actually before the splice point. 118 // Ensure the given buffers are actually before the splice point.
115 DCHECK(first_splice_buffer->timestamp() <= overlapping_buffer->timestamp()); 119 DCHECK(first_splice_buffer->timestamp() <= overlapping_buffer->timestamp());
116 120
117 // TODO(dalecurtis): We should also clear |data| and |side_data|, but since 121 // TODO(dalecurtis): We should also clear |data| and |side_data|, but since
118 // that implies EOS care must be taken to ensure there are no clients relying 122 // that implies EOS care must be taken to ensure there are no clients relying
119 // on that behavior. 123 // on that behavior.
120 124
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_);
129 }
130
121 // Rewrite |this| buffer as a splice buffer. 131 // Rewrite |this| buffer as a splice buffer.
122 SetDecodeTimestamp(first_splice_buffer->GetDecodeTimestamp()); 132 SetDecodeTimestamp(first_splice_buffer->GetDecodeTimestamp());
123 SetConfigId(first_splice_buffer->GetConfigId()); 133 SetConfigId(first_splice_buffer->GetConfigId());
124 set_timestamp(first_splice_buffer->timestamp()); 134 set_timestamp(first_splice_buffer->timestamp());
125 is_keyframe_ = first_splice_buffer->IsKeyframe(); 135 is_keyframe_ = first_splice_buffer->IsKeyframe();
126 type_ = first_splice_buffer->type(); 136 type_ = first_splice_buffer->type();
127 track_id_ = first_splice_buffer->track_id(); 137 track_id_ = first_splice_buffer->track_id();
128 set_splice_timestamp(overlapping_buffer->timestamp()); 138 set_splice_timestamp(overlapping_buffer->timestamp());
129 139
130 // The splice duration is the duration of all buffers before the splice plus 140 // The splice duration is the duration of all buffers before the splice plus
131 // the highest ending timestamp after the splice point. 141 // the highest ending timestamp after the splice point.
132 set_duration( 142 set_duration(
133 std::max(overlapping_buffer->timestamp() + overlapping_buffer->duration(), 143 std::max(overlapping_buffer->timestamp() + overlapping_buffer->duration(),
134 pre_splice_buffers.back()->timestamp() + 144 pre_splice_buffers.back()->timestamp() +
135 pre_splice_buffers.back()->duration()) - 145 pre_splice_buffers.back()->duration()) -
136 first_splice_buffer->timestamp()); 146 first_splice_buffer->timestamp());
137 147
138 // Copy all pre splice buffers into our wrapper buffer. 148 // Copy all pre splice buffers into our wrapper buffer.
139 for (BufferQueue::const_iterator it = pre_splice_buffers.begin(); 149 for (BufferQueue::const_iterator it = pre_splice_buffers.begin();
140 it != pre_splice_buffers.end(); 150 it != pre_splice_buffers.end();
141 ++it) { 151 ++it) {
142 const scoped_refptr<StreamParserBuffer>& buffer = *it; 152 const scoped_refptr<StreamParserBuffer>& buffer = *it;
143 DCHECK(!buffer->end_of_stream()); 153 DCHECK(!buffer->end_of_stream());
154 DCHECK(!buffer->preroll_buffer());
144 DCHECK(buffer->splice_buffers().empty()); 155 DCHECK(buffer->splice_buffers().empty());
145 splice_buffers_.push_back(CopyBuffer(*buffer)); 156 splice_buffers_.push_back(CopyBuffer(*buffer));
146 splice_buffers_.back()->set_splice_timestamp(splice_timestamp()); 157 splice_buffers_.back()->set_splice_timestamp(splice_timestamp());
147 } 158 }
148 159
149 splice_buffers_.push_back(overlapping_buffer); 160 splice_buffers_.push_back(overlapping_buffer);
150 } 161 }
151 162
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());
175
176 preroll_buffer_ = preroll_buffer;
177 preroll_buffer_->set_timestamp(timestamp());
178 preroll_buffer_->SetDecodeTimestamp(GetDecodeTimestamp());
179
180 // Mark the entire buffer for discard.
181 preroll_buffer_->set_discard_padding(
182 std::make_pair(kInfiniteDuration(), base::TimeDelta()));
183 }
184
185 void StreamParserBuffer::set_timestamp(base::TimeDelta timestamp) {
186 DecoderBuffer::set_timestamp(timestamp);
187 if (preroll_buffer_)
188 preroll_buffer_->set_timestamp(timestamp);
189 }
190
152 } // namespace media 191 } // namespace media
OLDNEW
« no previous file with comments | « media/base/stream_parser_buffer.h ('k') | media/filters/chunk_demuxer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698