Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |