diff options
author | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-06 23:33:06 +0000 |
---|---|---|
committer | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-06 23:33:06 +0000 |
commit | 11650c4d45daec8cce3002eb3ffad6a1dc7a95f1 (patch) | |
tree | 6c1a85a86da16b167f69ebcc238077356dca1e66 /media | |
parent | 553981ab338db3c606b13016f3fb236cf7d0924f (diff) | |
download | chromium_src-11650c4d45daec8cce3002eb3ffad6a1dc7a95f1.zip chromium_src-11650c4d45daec8cce3002eb3ffad6a1dc7a95f1.tar.gz chromium_src-11650c4d45daec8cce3002eb3ffad6a1dc7a95f1.tar.bz2 |
Add support for files that use AltRef frames.
BUG=131265
TEST=ChunkDemuxerTest.TestWebMFile_AltRefFrames
Review URL: https://chromiumcodereview.appspot.com/10542009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140883 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/filters/chunk_demuxer.cc | 6 | ||||
-rw-r--r-- | media/filters/chunk_demuxer_unittest.cc | 24 | ||||
-rw-r--r-- | media/webm/webm_cluster_parser.cc | 59 | ||||
-rw-r--r-- | media/webm/webm_cluster_parser.h | 10 |
4 files changed, 83 insertions, 16 deletions
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc index 1651c25..331b177 100644 --- a/media/filters/chunk_demuxer.cc +++ b/media/filters/chunk_demuxer.cc @@ -606,6 +606,7 @@ bool ChunkDemuxer::AppendData(const std::string& id, } void ChunkDemuxer::Abort(const std::string& id) { + DVLOG(1) << "Abort(" << id << ")"; DCHECK(!id.empty()); DCHECK_EQ(source_id_, id); @@ -673,6 +674,8 @@ void ChunkDemuxer::Shutdown() { void ChunkDemuxer::ChangeState_Locked(State new_state) { lock_.AssertAcquired(); + DVLOG(1) << "ChunkDemuxer::ChangeState_Locked() : " + << state_ << " -> " << new_state; state_ = new_state; } @@ -681,6 +684,7 @@ ChunkDemuxer::~ChunkDemuxer() { } void ChunkDemuxer::ReportError_Locked(PipelineStatus error) { + DVLOG(1) << "ReportError_Locked(" << error << ")"; lock_.AssertAcquired(); DCHECK_NE(error, PIPELINE_OK); @@ -732,6 +736,8 @@ bool ChunkDemuxer::CanEndOfStream_Locked() const { void ChunkDemuxer::OnStreamParserInitDone(bool success, base::TimeDelta duration) { + DVLOG(1) << "OnSourceBufferInitDone(" << success << ", " + << duration.InSecondsF() << ")"; lock_.AssertAcquired(); DCHECK_EQ(state_, INITIALIZING); if (!success || (!audio_ && !video_)) { diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc index a1de2d3..8c077d4 100644 --- a/media/filters/chunk_demuxer_unittest.cc +++ b/media/filters/chunk_demuxer_unittest.cc @@ -652,12 +652,12 @@ TEST_F(ChunkDemuxerTest, TestPerStreamMonotonicallyIncreasingTimestamps) { ClusterBuilder cb; - // Test strict monotonic increasing timestamps on a per stream + // Test monotonic increasing timestamps on a per stream // basis. cb.SetClusterTimecode(5); AddSimpleBlock(&cb, kAudioTrackNum, 5); AddSimpleBlock(&cb, kVideoTrackNum, 5); - AddSimpleBlock(&cb, kAudioTrackNum, 5); + AddSimpleBlock(&cb, kAudioTrackNum, 4); AddSimpleBlock(&cb, kVideoTrackNum, 7); scoped_ptr<Cluster> cluster(cb.Finish()); @@ -670,7 +670,7 @@ TEST_F(ChunkDemuxerTest, TestMonotonicallyIncreasingTimestampsAcrossClusters) { ClusterBuilder cb; - // Test strict monotonic increasing timestamps on a per stream + // Test monotonic increasing timestamps on a per stream // basis across clusters. cb.SetClusterTimecode(5); AddSimpleBlock(&cb, kAudioTrackNum, 5); @@ -679,8 +679,8 @@ TEST_F(ChunkDemuxerTest, TestMonotonicallyIncreasingTimestampsAcrossClusters) { ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); - cb.SetClusterTimecode(5); - AddSimpleBlock(&cb, kAudioTrackNum, 5); + cb.SetClusterTimecode(4); + AddSimpleBlock(&cb, kAudioTrackNum, 4); AddSimpleBlock(&cb, kVideoTrackNum, 7); scoped_ptr<Cluster> cluster_b(cb.Finish()); @@ -968,6 +968,20 @@ TEST_F(ChunkDemuxerTest, TestWebMFile_VideoOnly) { base::TimeDelta::FromMilliseconds(2703))); } +TEST_F(ChunkDemuxerTest, TestWebMFile_AltRefFrames) { + struct BufferTimestamps buffer_timestamps[] = { + {0, 0}, + {33, 3}, + {33, 6}, + {67, 9}, + {100, 12}, + {kSkip, kSkip}, + }; + + ASSERT_TRUE(ParseWebMFile("bear-320x240-altref.webm", buffer_timestamps, + base::TimeDelta::FromMilliseconds(2767))); +} + // Verify that we output buffers before the entire cluster has been parsed. TEST_F(ChunkDemuxerTest, TestIncrementalClusterParsing) { ASSERT_TRUE(InitDemuxer(true, true, false)); diff --git a/media/webm/webm_cluster_parser.cc b/media/webm/webm_cluster_parser.cc index 6cbd71d..5b18c56 100644 --- a/media/webm/webm_cluster_parser.cc +++ b/media/webm/webm_cluster_parser.cc @@ -230,38 +230,77 @@ bool WebMClusterParser::Track::AddBuffer( return false; } - if (delayed_buffer_) { + if (!delayed_buffers_.empty()) { // Update the duration of the delayed buffer and place it into the queue. + scoped_refptr<StreamParserBuffer> delayed_buffer = delayed_buffers_.front(); + + // If we get another buffer with the same timestamp, put it in the delay + // queue. + if (buffer->GetTimestamp() == delayed_buffer->GetTimestamp()) { + delayed_buffers_.push_back(buffer); + + // If this buffer happens to have a duration, use it to set the + // duration on all the other buffers in the queue. + if (buffer->GetDuration() != kNoTimestamp()) + SetDelayedBufferDurations(buffer->GetDuration()); + + return true; + } + base::TimeDelta new_duration = - buffer->GetTimestamp() - delayed_buffer_->GetTimestamp(); + buffer->GetTimestamp() - delayed_buffer->GetTimestamp(); - if (new_duration <= base::TimeDelta()) + if (new_duration < base::TimeDelta()) { + DVLOG(1) << "Detected out of order timestamps."; return false; + } - delayed_buffer_->SetDuration(new_duration); - buffers_.push_back(delayed_buffer_); - - delayed_buffer_ = NULL; + SetDelayedBufferDurations(new_duration); } // Place the buffer in delayed buffer slot if we don't know // its duration. if (buffer->GetDuration() == kNoTimestamp()) { - delayed_buffer_ = buffer; + delayed_buffers_.push_back(buffer); return true; } - buffers_.push_back(buffer); + AddToBufferQueue(buffer); return true; } void WebMClusterParser::Track::Reset() { buffers_.clear(); - delayed_buffer_ = NULL; + delayed_buffers_.clear(); } void WebMClusterParser::Track::ClearBufferQueue() { buffers_.clear(); } +void WebMClusterParser::Track::SetDelayedBufferDurations( + base::TimeDelta duration) { + + for (BufferQueue::iterator itr = delayed_buffers_.begin(); + itr < delayed_buffers_.end(); ++itr) { + (*itr)->SetDuration(duration); + + AddToBufferQueue(*itr); + } + delayed_buffers_.clear(); +} + +void WebMClusterParser::Track::AddToBufferQueue( + const scoped_refptr<StreamParserBuffer>& buffer) { + DCHECK(buffer->GetDuration() > base::TimeDelta()); + + DVLOG(2) << "AddToBufferQueue() : " << track_num_ + << " ts " << buffer->GetTimestamp().InSecondsF() + << " dur " << buffer->GetDuration().InSecondsF() + << " kf " << buffer->IsKeyframe() + << " size " << buffer->GetDataSize(); + + buffers_.push_back(buffer); +} + } // namespace media diff --git a/media/webm/webm_cluster_parser.h b/media/webm/webm_cluster_parser.h index 159fd38..c702d10 100644 --- a/media/webm/webm_cluster_parser.h +++ b/media/webm/webm_cluster_parser.h @@ -58,9 +58,17 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { void ClearBufferQueue(); private: + // Sets the duration of all the buffers in |delayed_buffers_| + // and then moves these buffers into |buffers_|. |delayed_buffers_| + // is empty when this call returns. + void SetDelayedBufferDurations(base::TimeDelta duration); + + // Adds the buffer to |buffers_|. |buffer| must have its duration set. + void AddToBufferQueue(const scoped_refptr<StreamParserBuffer>& buffer); + int track_num_; BufferQueue buffers_; - scoped_refptr<StreamParserBuffer> delayed_buffer_; + BufferQueue delayed_buffers_; }; // WebMParserClient methods. |