summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authoracolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-06 23:33:06 +0000
committeracolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-06 23:33:06 +0000
commit11650c4d45daec8cce3002eb3ffad6a1dc7a95f1 (patch)
tree6c1a85a86da16b167f69ebcc238077356dca1e66 /media
parent553981ab338db3c606b13016f3fb236cf7d0924f (diff)
downloadchromium_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.cc6
-rw-r--r--media/filters/chunk_demuxer_unittest.cc24
-rw-r--r--media/webm/webm_cluster_parser.cc59
-rw-r--r--media/webm/webm_cluster_parser.h10
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.