| Index: media/webm/webm_cluster_parser.cc
|
| diff --git a/media/webm/webm_cluster_parser.cc b/media/webm/webm_cluster_parser.cc
|
| index ed1e94eafdbf403004a19d327c47314fff88c23c..8271899074deac922e3ca3888e753b73596d3480 100644
|
| --- a/media/webm/webm_cluster_parser.cc
|
| +++ b/media/webm/webm_cluster_parser.cc
|
| @@ -19,16 +19,14 @@ WebMClusterParser::WebMClusterParser(int64 timecode_scale,
|
| const uint8* video_encryption_key_id,
|
| int video_encryption_key_id_size)
|
| : timecode_multiplier_(timecode_scale / 1000.0),
|
| - audio_track_num_(audio_track_num),
|
| - audio_default_duration_(audio_default_duration),
|
| - video_track_num_(video_track_num),
|
| - video_default_duration_(video_default_duration),
|
| video_encryption_key_id_size_(video_encryption_key_id_size),
|
| parser_(kWebMIdCluster, this),
|
| last_block_timecode_(-1),
|
| block_data_size_(-1),
|
| block_duration_(-1),
|
| - cluster_timecode_(-1) {
|
| + cluster_timecode_(-1),
|
| + audio_(audio_track_num, audio_default_duration),
|
| + video_(video_track_num, video_default_duration) {
|
| CHECK_GE(video_encryption_key_id_size, 0);
|
| if (video_encryption_key_id_size > 0) {
|
| video_encryption_key_id_.reset(new uint8[video_encryption_key_id_size]);
|
| @@ -40,16 +38,16 @@ WebMClusterParser::WebMClusterParser(int64 timecode_scale,
|
| WebMClusterParser::~WebMClusterParser() {}
|
|
|
| void WebMClusterParser::Reset() {
|
| - audio_buffers_.clear();
|
| - video_buffers_.clear();
|
| last_block_timecode_ = -1;
|
| cluster_timecode_ = -1;
|
| parser_.Reset();
|
| + audio_.Reset();
|
| + video_.Reset();
|
| }
|
|
|
| int WebMClusterParser::Parse(const uint8* buf, int size) {
|
| - audio_buffers_.clear();
|
| - video_buffers_.clear();
|
| + audio_.ClearBufferQueue();
|
| + video_.ClearBufferQueue();
|
|
|
| int result = parser_.Parse(buf, size);
|
|
|
| @@ -166,6 +164,7 @@ bool WebMClusterParser::OnBinary(int id, const uint8* data, int size) {
|
| block_data_size_ = size;
|
| return true;
|
| }
|
| +
|
| bool WebMClusterParser::OnBlock(int track_num, int timecode,
|
| int block_duration,
|
| int flags,
|
| @@ -196,42 +195,80 @@ bool WebMClusterParser::OnBlock(int track_num, int timecode,
|
| scoped_refptr<StreamParserBuffer> buffer =
|
| StreamParserBuffer::CopyFrom(data, size, is_keyframe);
|
|
|
| - if (track_num == video_track_num_ && video_encryption_key_id_.get()) {
|
| + if (track_num == video_.track_num() && video_encryption_key_id_.get()) {
|
| buffer->SetDecryptConfig(scoped_ptr<DecryptConfig>(new DecryptConfig(
|
| video_encryption_key_id_.get(), video_encryption_key_id_size_)));
|
| }
|
|
|
| buffer->SetTimestamp(timestamp);
|
| - BufferQueue* queue = NULL;
|
| - base::TimeDelta duration = kNoTimestamp();
|
| -
|
| - if (track_num == audio_track_num_) {
|
| - duration = audio_default_duration_;
|
| - queue = &audio_buffers_;
|
| - } else if (track_num == video_track_num_) {
|
| - duration = video_default_duration_;
|
| - queue = &video_buffers_;
|
| - } else {
|
| - DVLOG(1) << "Unexpected track number " << track_num;
|
| - return false;
|
| - }
|
|
|
| if (block_duration >= 0) {
|
| - duration = base::TimeDelta::FromMicroseconds(
|
| - block_duration * timecode_multiplier_);
|
| + buffer->SetDuration(base::TimeDelta::FromMicroseconds(
|
| + block_duration * timecode_multiplier_));
|
| }
|
|
|
| - buffer->SetDuration(duration);
|
| + if (track_num == audio_.track_num()) {
|
| + return audio_.AddBuffer(buffer);
|
| + } else if (track_num == video_.track_num()) {
|
| + return video_.AddBuffer(buffer);
|
| + }
|
| +
|
| + DVLOG(1) << "Unexpected track number " << track_num;
|
| + return false;
|
| +}
|
| +
|
| +WebMClusterParser::Track::Track(int track_num,
|
| + base::TimeDelta default_duration)
|
| + : track_num_(track_num),
|
| + default_duration_(default_duration) {
|
| +}
|
| +
|
| +WebMClusterParser::Track::~Track() {}
|
|
|
| - if (!queue->empty() &&
|
| - buffer->GetTimestamp() == queue->back()->GetTimestamp()) {
|
| +bool WebMClusterParser::Track::AddBuffer(
|
| + const scoped_refptr<StreamParserBuffer>& buffer) {
|
| + if (!buffers_.empty() &&
|
| + buffer->GetTimestamp() == buffers_.back()->GetTimestamp()) {
|
| DVLOG(1) << "Got a block timecode that is not strictly monotonically "
|
| - << "increasing for track " << track_num;
|
| + << "increasing for track " << track_num_;
|
| return false;
|
| }
|
|
|
| - queue->push_back(buffer);
|
| + if (buffer->GetDuration() == kNoTimestamp())
|
| + buffer->SetDuration(default_duration_);
|
| +
|
| + if (delayed_buffer_) {
|
| + // Update the duration of the delayed buffer and place it into the queue.
|
| + base::TimeDelta new_duration =
|
| + buffer->GetTimestamp() - delayed_buffer_->GetTimestamp();
|
| +
|
| + if (new_duration <= base::TimeDelta())
|
| + return false;
|
| +
|
| + delayed_buffer_->SetDuration(new_duration);
|
| + buffers_.push_back(delayed_buffer_);
|
| +
|
| + delayed_buffer_ = NULL;
|
| + }
|
| +
|
| + // Place the buffer in delayed buffer slot if we don't know
|
| + // its duration.
|
| + if (buffer->GetDuration() == kNoTimestamp()) {
|
| + delayed_buffer_ = buffer;
|
| + return true;
|
| + }
|
| +
|
| + buffers_.push_back(buffer);
|
| return true;
|
| }
|
|
|
| +void WebMClusterParser::Track::Reset() {
|
| + buffers_.clear();
|
| + delayed_buffer_ = NULL;
|
| +}
|
| +
|
| +void WebMClusterParser::Track::ClearBufferQueue() {
|
| + buffers_.clear();
|
| +}
|
| +
|
| } // namespace media
|
|
|