diff options
author | vrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-29 23:35:01 +0000 |
---|---|---|
committer | vrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-29 23:35:01 +0000 |
commit | 124be785d77b48e4df7fe1cb1a3a94f2b59bb3d1 (patch) | |
tree | a7bfa88aeca9f47078453edc9e24da6998f49c15 /media | |
parent | baef1ffd73db183ca50c854e1779ed7f6e5100a8 (diff) | |
download | chromium_src-124be785d77b48e4df7fe1cb1a3a94f2b59bb3d1.zip chromium_src-124be785d77b48e4df7fe1cb1a3a94f2b59bb3d1.tar.gz chromium_src-124be785d77b48e4df7fe1cb1a3a94f2b59bb3d1.tar.bz2 |
Add support to WebMClusterParser to accept clusters without blocks
BUG=NONE
TEST=media_unittests
Review URL: https://chromiumcodereview.appspot.com/10673012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@145030 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/filters/chunk_demuxer_unittest.cc | 24 | ||||
-rw-r--r-- | media/webm/webm_cluster_parser.cc | 18 | ||||
-rw-r--r-- | media/webm/webm_cluster_parser.h | 2 | ||||
-rw-r--r-- | media/webm/webm_stream_parser.cc | 20 |
4 files changed, 42 insertions, 22 deletions
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc index cd1d96f..2494c9f 100644 --- a/media/filters/chunk_demuxer_unittest.cc +++ b/media/filters/chunk_demuxer_unittest.cc @@ -466,6 +466,12 @@ class ChunkDemuxerTest : public testing::Test { } } + scoped_ptr<Cluster> GenerateEmptyCluster(int timecode) { + ClusterBuilder cb; + cb.SetClusterTimecode(timecode); + return cb.Finish(); + } + void CheckExpectedRanges(const std::string& expected) { CheckExpectedRanges(kSourceId, expected); } @@ -1618,6 +1624,24 @@ TEST_F(ChunkDemuxerTest, TestDifferentStreamTimecodes) { GenerateExpectedReads(5025, 5000, 8, audio, video); } +TEST_F(ChunkDemuxerTest, TestClusterWithNoBuffers) { + ASSERT_TRUE(InitDemuxer(true, true, false)); + + // Create an empty cluster beginning at 0. + scoped_ptr<Cluster> empty_cluster(GenerateEmptyCluster(0)); + ASSERT_TRUE(AppendData(empty_cluster->data(), empty_cluster->size())); + + // Sanity check that data can be appended after this cluster correctly. + scoped_ptr<Cluster> media_data(GenerateCluster(0, 2)); + ASSERT_TRUE(AppendData(media_data->data(), media_data->size())); + scoped_refptr<DemuxerStream> audio = + demuxer_->GetStream(DemuxerStream::AUDIO); + scoped_refptr<DemuxerStream> video = + demuxer_->GetStream(DemuxerStream::VIDEO); + ExpectRead(audio, 0); + ExpectRead(video, 0); +} + TEST_F(ChunkDemuxerTest, TestCodecPrefixMatching) { ChunkDemuxer::Status expected = ChunkDemuxer::kNotSupported; diff --git a/media/webm/webm_cluster_parser.cc b/media/webm/webm_cluster_parser.cc index 5b18c56..be5e724 100644 --- a/media/webm/webm_cluster_parser.cc +++ b/media/webm/webm_cluster_parser.cc @@ -23,6 +23,7 @@ WebMClusterParser::WebMClusterParser(int64 timecode_scale, block_data_size_(-1), block_duration_(-1), cluster_timecode_(-1), + cluster_start_time_(kNoTimestamp()), audio_(audio_track_num), video_(video_track_num) { CHECK_GE(video_encryption_key_id_size, 0); @@ -38,6 +39,7 @@ WebMClusterParser::~WebMClusterParser() {} void WebMClusterParser::Reset() { last_block_timecode_ = -1; cluster_timecode_ = -1; + cluster_start_time_ = kNoTimestamp(); parser_.Reset(); audio_.Reset(); video_.Reset(); @@ -53,6 +55,14 @@ int WebMClusterParser::Parse(const uint8* buf, int size) { return result; if (parser_.IsParsingComplete()) { + // If there were no buffers in this cluster, set the cluster start time to + // be the |cluster_timecode_|. + if (cluster_start_time_ == kNoTimestamp()) { + DCHECK_GT(cluster_timecode_, -1); + cluster_start_time_ = base::TimeDelta::FromMicroseconds( + cluster_timecode_ * timecode_multiplier_); + } + // Reset the parser if we're done parsing so that // it is ready to accept another cluster on the next // call. @@ -68,6 +78,7 @@ int WebMClusterParser::Parse(const uint8* buf, int size) { WebMParserClient* WebMClusterParser::OnListStart(int id) { if (id == kWebMIdCluster) { cluster_timecode_ = -1; + cluster_start_time_ = kNoTimestamp(); } else if (id == kWebMIdBlockGroup) { block_data_.reset(); block_data_size_ = -1; @@ -78,11 +89,6 @@ WebMParserClient* WebMClusterParser::OnListStart(int id) { } bool WebMClusterParser::OnListEnd(int id) { - if (id == kWebMIdCluster) { - cluster_timecode_ = -1; - return true; - } - if (id != kWebMIdBlockGroup) return true; @@ -199,6 +205,8 @@ bool WebMClusterParser::OnBlock(int track_num, int timecode, } buffer->SetTimestamp(timestamp); + if (cluster_start_time_ == kNoTimestamp()) + cluster_start_time_ = timestamp; if (block_duration >= 0) { buffer->SetDuration(base::TimeDelta::FromMicroseconds( diff --git a/media/webm/webm_cluster_parser.h b/media/webm/webm_cluster_parser.h index c702d10..ea76d30 100644 --- a/media/webm/webm_cluster_parser.h +++ b/media/webm/webm_cluster_parser.h @@ -36,6 +36,7 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { // Returns the number of bytes parsed on success. int Parse(const uint8* buf, int size); + base::TimeDelta cluster_start_time() const { return cluster_start_time_; } const BufferQueue& audio_buffers() const { return audio_.buffers(); } const BufferQueue& video_buffers() const { return video_.buffers(); } @@ -94,6 +95,7 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { int64 block_duration_; int64 cluster_timecode_; + base::TimeDelta cluster_start_time_; Track audio_; Track video_; diff --git a/media/webm/webm_stream_parser.cc b/media/webm/webm_stream_parser.cc index e1ed947..602d227 100644 --- a/media/webm/webm_stream_parser.cc +++ b/media/webm/webm_stream_parser.cc @@ -409,24 +409,10 @@ int WebMStreamParser::ParseCluster(const uint8* data, int size) { const BufferQueue& audio_buffers = cluster_parser_->audio_buffers(); const BufferQueue& video_buffers = cluster_parser_->video_buffers(); + base::TimeDelta cluster_start_time = cluster_parser_->cluster_start_time(); - if (waiting_for_buffers_) { - base::TimeDelta audio_start_timestamp = kInfiniteDuration(); - base::TimeDelta video_start_timestamp = kInfiniteDuration(); - - if (!audio_buffers.empty()) - audio_start_timestamp = audio_buffers.front()->GetTimestamp(); - if (!video_buffers.empty()) - video_start_timestamp = video_buffers.front()->GetTimestamp(); - - base::TimeDelta cluster_start_timestamp = - std::min(audio_start_timestamp, video_start_timestamp); - - // If we haven't gotten any buffers yet, return early. - if (cluster_start_timestamp == kInfiniteDuration()) - return bytes_parsed; - - new_segment_cb_.Run(cluster_start_timestamp); + if (waiting_for_buffers_ && cluster_start_time != kNoTimestamp()) { + new_segment_cb_.Run(cluster_start_time); waiting_for_buffers_ = false; } |