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

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: Address CR comments 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
« no previous file with comments | « media/webm/webm_cluster_parser.h ('k') | media/webm/webm_cluster_parser_unittest.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/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"
11 11
12 namespace media { 12 namespace media {
13 13
14 WebMClusterParser::WebMClusterParser(int64 timecode_scale, 14 WebMClusterParser::WebMClusterParser(int64 timecode_scale,
15 int audio_track_num, 15 int audio_track_num,
16 base::TimeDelta audio_default_duration, 16 base::TimeDelta audio_default_duration,
17 int video_track_num, 17 int video_track_num,
18 base::TimeDelta video_default_duration, 18 base::TimeDelta video_default_duration,
19 const uint8* video_encryption_key_id, 19 const uint8* video_encryption_key_id,
20 int video_encryption_key_id_size) 20 int video_encryption_key_id_size)
21 : timecode_multiplier_(timecode_scale / 1000.0), 21 : timecode_multiplier_(timecode_scale / 1000.0),
22 audio_track_num_(audio_track_num),
23 audio_default_duration_(audio_default_duration),
24 video_track_num_(video_track_num),
25 video_default_duration_(video_default_duration),
26 video_encryption_key_id_size_(video_encryption_key_id_size), 22 video_encryption_key_id_size_(video_encryption_key_id_size),
27 parser_(kWebMIdCluster, this), 23 parser_(kWebMIdCluster, this),
28 last_block_timecode_(-1), 24 last_block_timecode_(-1),
29 block_data_size_(-1), 25 block_data_size_(-1),
30 block_duration_(-1), 26 block_duration_(-1),
31 cluster_timecode_(-1) { 27 cluster_timecode_(-1),
28 audio_(audio_track_num, audio_default_duration),
29 video_(video_track_num, video_default_duration) {
32 CHECK_GE(video_encryption_key_id_size, 0); 30 CHECK_GE(video_encryption_key_id_size, 0);
33 if (video_encryption_key_id_size > 0) { 31 if (video_encryption_key_id_size > 0) {
34 video_encryption_key_id_.reset(new uint8[video_encryption_key_id_size]); 32 video_encryption_key_id_.reset(new uint8[video_encryption_key_id_size]);
35 memcpy(video_encryption_key_id_.get(), video_encryption_key_id, 33 memcpy(video_encryption_key_id_.get(), video_encryption_key_id,
36 video_encryption_key_id_size); 34 video_encryption_key_id_size);
37 } 35 }
38 } 36 }
39 37
40 WebMClusterParser::~WebMClusterParser() {} 38 WebMClusterParser::~WebMClusterParser() {}
41 39
42 void WebMClusterParser::Reset() { 40 void WebMClusterParser::Reset() {
43 audio_buffers_.clear();
44 video_buffers_.clear();
45 last_block_timecode_ = -1; 41 last_block_timecode_ = -1;
46 cluster_timecode_ = -1; 42 cluster_timecode_ = -1;
47 parser_.Reset(); 43 parser_.Reset();
44 audio_.Reset();
45 video_.Reset();
48 } 46 }
49 47
50 int WebMClusterParser::Parse(const uint8* buf, int size) { 48 int WebMClusterParser::Parse(const uint8* buf, int size) {
51 audio_buffers_.clear(); 49 audio_.ClearBufferQueue();
52 video_buffers_.clear(); 50 video_.ClearBufferQueue();
53 51
54 int result = parser_.Parse(buf, size); 52 int result = parser_.Parse(buf, size);
55 53
56 if (result <= 0) 54 if (result <= 0)
57 return result; 55 return result;
58 56
59 if (parser_.IsParsingComplete()) { 57 if (parser_.IsParsingComplete()) {
60 // Reset the parser if we're done parsing so that 58 // Reset the parser if we're done parsing so that
61 // it is ready to accept another cluster on the next 59 // it is ready to accept another cluster on the next
62 // call. 60 // call.
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 if (block_data_.get()) { 157 if (block_data_.get()) {
160 DVLOG(1) << "More than 1 Block in a BlockGroup is not supported."; 158 DVLOG(1) << "More than 1 Block in a BlockGroup is not supported.";
161 return false; 159 return false;
162 } 160 }
163 161
164 block_data_.reset(new uint8[size]); 162 block_data_.reset(new uint8[size]);
165 memcpy(block_data_.get(), data, size); 163 memcpy(block_data_.get(), data, size);
166 block_data_size_ = size; 164 block_data_size_ = size;
167 return true; 165 return true;
168 } 166 }
167
169 bool WebMClusterParser::OnBlock(int track_num, int timecode, 168 bool WebMClusterParser::OnBlock(int track_num, int timecode,
170 int block_duration, 169 int block_duration,
171 int flags, 170 int flags,
172 const uint8* data, int size) { 171 const uint8* data, int size) {
173 if (cluster_timecode_ == -1) { 172 if (cluster_timecode_ == -1) {
174 DVLOG(1) << "Got a block before cluster timecode."; 173 DVLOG(1) << "Got a block before cluster timecode.";
175 return false; 174 return false;
176 } 175 }
177 176
178 if (timecode < 0) { 177 if (timecode < 0) {
(...skipping 10 matching lines...) Expand all
189 188
190 base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds( 189 base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds(
191 (cluster_timecode_ + timecode) * timecode_multiplier_); 190 (cluster_timecode_ + timecode) * timecode_multiplier_);
192 191
193 // The first bit of the flags is set when the block contains only keyframes. 192 // The first bit of the flags is set when the block contains only keyframes.
194 // http://www.matroska.org/technical/specs/index.html 193 // http://www.matroska.org/technical/specs/index.html
195 bool is_keyframe = (flags & 0x80) != 0; 194 bool is_keyframe = (flags & 0x80) != 0;
196 scoped_refptr<StreamParserBuffer> buffer = 195 scoped_refptr<StreamParserBuffer> buffer =
197 StreamParserBuffer::CopyFrom(data, size, is_keyframe); 196 StreamParserBuffer::CopyFrom(data, size, is_keyframe);
198 197
199 if (track_num == video_track_num_ && video_encryption_key_id_.get()) { 198 if (track_num == video_.track_num() && video_encryption_key_id_.get()) {
200 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig( 199 buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig(
201 video_encryption_key_id_.get(), video_encryption_key_id_size_))); 200 video_encryption_key_id_.get(), video_encryption_key_id_size_)));
202 } 201 }
203 202
204 buffer->SetTimestamp(timestamp); 203 buffer->SetTimestamp(timestamp);
205 BufferQueue* queue = NULL;
206 base::TimeDelta duration = kNoTimestamp();
207 204
208 if (track_num == audio_track_num_) { 205 if (block_duration >= 0) {
209 duration = audio_default_duration_; 206 buffer->SetDuration(base::TimeDelta::FromMicroseconds(
210 queue = &audio_buffers_; 207 block_duration * timecode_multiplier_));
211 } else if (track_num == video_track_num_) { 208 }
212 duration = video_default_duration_; 209
213 queue = &video_buffers_; 210 if (track_num == audio_.track_num()) {
214 } else { 211 return audio_.AddBuffer(buffer);
215 DVLOG(1) << "Unexpected track number " << track_num; 212 } else if (track_num == video_.track_num()) {
213 return video_.AddBuffer(buffer);
214 }
215
216 DVLOG(1) << "Unexpected track number " << track_num;
217 return false;
218 }
219
220 WebMClusterParser::Track::Track(int track_num,
221 base::TimeDelta default_duration)
222 : track_num_(track_num),
223 default_duration_(default_duration) {
224 }
225
226 WebMClusterParser::Track::~Track() {}
227
228 bool WebMClusterParser::Track::AddBuffer(
229 const scoped_refptr<StreamParserBuffer>& buffer) {
230 if (!buffers_.empty() &&
231 buffer->GetTimestamp() == buffers_.back()->GetTimestamp()) {
232 DVLOG(1) << "Got a block timecode that is not strictly monotonically "
233 << "increasing for track " << track_num_;
216 return false; 234 return false;
217 } 235 }
218 236
219 if (block_duration >= 0) { 237 if (buffer->GetDuration() == kNoTimestamp())
220 duration = base::TimeDelta::FromMicroseconds( 238 buffer->SetDuration(default_duration_);
221 block_duration * timecode_multiplier_); 239
240 if (delayed_buffer_) {
241 // Update the duration of the delayed buffer and place it into the queue.
242 base::TimeDelta new_duration =
243 buffer->GetTimestamp() - delayed_buffer_->GetTimestamp();
244
245 if (new_duration <= base::TimeDelta())
246 return false;
247
248 delayed_buffer_->SetDuration(new_duration);
249 buffers_.push_back(delayed_buffer_);
250
251 delayed_buffer_ = NULL;
222 } 252 }
223 253
224 buffer->SetDuration(duration); 254 // Place the buffer in delayed buffer slot if we don't know
225 255 // its duration.
226 if (!queue->empty() && 256 if (buffer->GetDuration() == kNoTimestamp()) {
227 buffer->GetTimestamp() == queue->back()->GetTimestamp()) { 257 delayed_buffer_ = buffer;
228 DVLOG(1) << "Got a block timecode that is not strictly monotonically " 258 return true;
229 << "increasing for track " << track_num;
230 return false;
231 } 259 }
232 260
233 queue->push_back(buffer); 261 buffers_.push_back(buffer);
234 return true; 262 return true;
235 } 263 }
236 264
265 void WebMClusterParser::Track::Reset() {
266 buffers_.clear();
267 delayed_buffer_ = NULL;
268 }
269
270 void WebMClusterParser::Track::ClearBufferQueue() {
271 buffers_.clear();
272 }
273
237 } // namespace media 274 } // namespace media
OLDNEW
« no previous file with comments | « media/webm/webm_cluster_parser.h ('k') | media/webm/webm_cluster_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698