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

Side by Side Diff: media/webm/webm_cluster_parser.cc

Issue 10382200: Update WebMClusterParser to compute durations for all StreamParserBuffers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix ChunkDemuxerAbortRead_AudioOnly Created 8 years, 7 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
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/webm/webm_cluster_parser.h" 5 #include "media/webm/webm_cluster_parser.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "media/base/data_buffer.h" 8 #include "media/base/data_buffer.h"
9 #include "media/base/decrypt_config.h" 9 #include "media/base/decrypt_config.h"
10 #include "media/webm/webm_constants.h" 10 #include "media/webm/webm_constants.h"
(...skipping 23 matching lines...) Expand all
34 video_encryption_key_id_.reset(new uint8[video_encryption_key_id_size]); 34 video_encryption_key_id_.reset(new uint8[video_encryption_key_id_size]);
35 memcpy(video_encryption_key_id_.get(), video_encryption_key_id, 35 memcpy(video_encryption_key_id_.get(), video_encryption_key_id,
36 video_encryption_key_id_size); 36 video_encryption_key_id_size);
37 } 37 }
38 } 38 }
39 39
40 WebMClusterParser::~WebMClusterParser() {} 40 WebMClusterParser::~WebMClusterParser() {}
41 41
42 void WebMClusterParser::Reset() { 42 void WebMClusterParser::Reset() {
43 audio_buffers_.clear(); 43 audio_buffers_.clear();
44 delayed_audio_buffer_ = NULL;
44 video_buffers_.clear(); 45 video_buffers_.clear();
46 delayed_video_buffer_ = NULL;
45 last_block_timecode_ = -1; 47 last_block_timecode_ = -1;
46 cluster_timecode_ = -1; 48 cluster_timecode_ = -1;
47 parser_.Reset(); 49 parser_.Reset();
48 } 50 }
49 51
50 int WebMClusterParser::Parse(const uint8* buf, int size) { 52 int WebMClusterParser::Parse(const uint8* buf, int size) {
51 audio_buffers_.clear(); 53 audio_buffers_.clear();
52 video_buffers_.clear(); 54 video_buffers_.clear();
53 55
54 int result = parser_.Parse(buf, size); 56 int result = parser_.Parse(buf, size);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 if (block_data_.get()) { 161 if (block_data_.get()) {
160 DVLOG(1) << "More than 1 Block in a BlockGroup is not supported."; 162 DVLOG(1) << "More than 1 Block in a BlockGroup is not supported.";
161 return false; 163 return false;
162 } 164 }
163 165
164 block_data_.reset(new uint8[size]); 166 block_data_.reset(new uint8[size]);
165 memcpy(block_data_.get(), data, size); 167 memcpy(block_data_.get(), data, size);
166 block_data_size_ = size; 168 block_data_size_ = size;
167 return true; 169 return true;
168 } 170 }
171
169 bool WebMClusterParser::OnBlock(int track_num, int timecode, 172 bool WebMClusterParser::OnBlock(int track_num, int timecode,
170 int block_duration, 173 int block_duration,
171 int flags, 174 int flags,
172 const uint8* data, int size) { 175 const uint8* data, int size) {
173 if (cluster_timecode_ == -1) { 176 if (cluster_timecode_ == -1) {
174 DVLOG(1) << "Got a block before cluster timecode."; 177 DVLOG(1) << "Got a block before cluster timecode.";
175 return false; 178 return false;
176 } 179 }
177 180
178 if (timecode < 0) { 181 if (timecode < 0) {
(...skipping 17 matching lines...) Expand all
196 scoped_refptr<StreamParserBuffer> buffer = 199 scoped_refptr<StreamParserBuffer> buffer =
197 StreamParserBuffer::CopyFrom(data, size, is_keyframe); 200 StreamParserBuffer::CopyFrom(data, size, is_keyframe);
198 201
199 if (track_num == video_track_num_ && video_encryption_key_id_.get()) { 202 if (track_num == video_track_num_ && video_encryption_key_id_.get()) {
200 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig( 203 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig(
201 video_encryption_key_id_.get(), video_encryption_key_id_size_))); 204 video_encryption_key_id_.get(), video_encryption_key_id_size_)));
202 } 205 }
203 206
204 buffer->SetTimestamp(timestamp); 207 buffer->SetTimestamp(timestamp);
205 BufferQueue* queue = NULL; 208 BufferQueue* queue = NULL;
209 scoped_refptr<StreamParserBuffer>* delayed_buffer;
scherkus (not reviewing) 2012/05/17 02:45:46 I'm finding this pointer-to-a-scoped_refptr<T> to
acolwell GONE FROM CHROMIUM 2012/05/17 18:28:51 Excellent idea! I moved this all into a helper cla
206 base::TimeDelta duration = kNoTimestamp(); 210 base::TimeDelta duration = kNoTimestamp();
207 211
208 if (track_num == audio_track_num_) { 212 if (track_num == audio_track_num_) {
209 duration = audio_default_duration_; 213 duration = audio_default_duration_;
210 queue = &audio_buffers_; 214 queue = &audio_buffers_;
215 delayed_buffer = &delayed_audio_buffer_;
211 } else if (track_num == video_track_num_) { 216 } else if (track_num == video_track_num_) {
212 duration = video_default_duration_; 217 duration = video_default_duration_;
213 queue = &video_buffers_; 218 queue = &video_buffers_;
219 delayed_buffer = &delayed_video_buffer_;
214 } else { 220 } else {
215 DVLOG(1) << "Unexpected track number " << track_num; 221 DVLOG(1) << "Unexpected track number " << track_num;
216 return false; 222 return false;
217 } 223 }
218 224
219 if (block_duration >= 0) { 225 if (block_duration >= 0) {
220 duration = base::TimeDelta::FromMicroseconds( 226 duration = base::TimeDelta::FromMicroseconds(
221 block_duration * timecode_multiplier_); 227 block_duration * timecode_multiplier_);
222 } 228 }
223 229
224 buffer->SetDuration(duration); 230 buffer->SetDuration(duration);
225 231
226 if (!queue->empty() && 232 if (!queue->empty() &&
227 buffer->GetTimestamp() == queue->back()->GetTimestamp()) { 233 buffer->GetTimestamp() == queue->back()->GetTimestamp()) {
228 DVLOG(1) << "Got a block timecode that is not strictly monotonically " 234 DVLOG(1) << "Got a block timecode that is not strictly monotonically "
229 << "increasing for track " << track_num; 235 << "increasing for track " << track_num;
230 return false; 236 return false;
231 } 237 }
232 238
239 if (*delayed_buffer) {
240 // Update the duration of the delayed buffer and place it into the queue.
241 base::TimeDelta new_duration =
242 buffer->GetTimestamp() - (*delayed_buffer)->GetTimestamp();
243
244 if (new_duration <= base::TimeDelta())
scherkus (not reviewing) 2012/05/17 02:45:46 when would this happen? out of order timestamps?
acolwell GONE FROM CHROMIUM 2012/05/17 18:28:51 Yes. It can happen if a muxer creates a cluster wi
245 return false;
246
247 (*delayed_buffer)->SetDuration(new_duration);
248 queue->push_back(*delayed_buffer);
249
250 *delayed_buffer = NULL;
251 }
252
253 // Place the buffer in delayed buffer slot if we don't know
254 // its duration.
255 if (buffer->GetDuration() == kNoTimestamp()) {
256 *delayed_buffer = buffer;
257 return true;
258 }
259
233 queue->push_back(buffer); 260 queue->push_back(buffer);
234 return true; 261 return true;
235 } 262 }
236 263
237 } // namespace media 264 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698