summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authoracolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-11 15:15:28 +0000
committeracolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-11 15:15:28 +0000
commite563a9456c981eb07c4bae91eb39b5de3c339900 (patch)
treefe53b471041856090a8882d27563070cd35aad17 /media
parentb248ecdda188dd6341c941c76b386d73fca7498e (diff)
downloadchromium_src-e563a9456c981eb07c4bae91eb39b5de3c339900.zip
chromium_src-e563a9456c981eb07c4bae91eb39b5de3c339900.tar.gz
chromium_src-e563a9456c981eb07c4bae91eb39b5de3c339900.tar.bz2
Refactor ChunkDemuxer initialization so INFO & TRACKS elements are passed via appendData().
BUG=86536 TEST=ChunkDemuxerTest.* Review URL: http://codereview.chromium.org/7329026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92011 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/filters/chunk_demuxer.cc133
-rw-r--r--media/filters/chunk_demuxer.h22
-rw-r--r--media/filters/chunk_demuxer_factory.cc139
-rw-r--r--media/filters/chunk_demuxer_factory.h9
-rw-r--r--media/filters/chunk_demuxer_unittest.cc76
5 files changed, 186 insertions, 193 deletions
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc
index 67877de..eb8412d 100644
--- a/media/filters/chunk_demuxer.cc
+++ b/media/filters/chunk_demuxer.cc
@@ -283,53 +283,20 @@ ChunkDemuxer::~ChunkDemuxer() {
format_context_ = NULL;
}
-bool ChunkDemuxer::Init(const uint8* data, int size) {
- DCHECK(data);
- DCHECK_GT(size, 0);
-
+void ChunkDemuxer::Init(PipelineStatusCB cb) {
base::AutoLock auto_lock(lock_);
DCHECK_EQ(state_, WAITING_FOR_INIT);
- const uint8* cur = data;
- int cur_size = size;
- WebMInfoParser info_parser;
- int res = info_parser.Parse(cur, cur_size);
-
- if (res <= 0) {
- ChangeState(INIT_ERROR);
- return false;
- }
-
- cur += res;
- cur_size -= res;
-
- WebMTracksParser tracks_parser(info_parser.timecode_scale());
- res = tracks_parser.Parse(cur, cur_size);
+ ChangeState(INITIALIZING);
+ init_cb_ = cb;
- if (res <= 0) {
- ChangeState(INIT_ERROR);
- return false;
- }
-
- double mult = info_parser.timecode_scale() / 1000.0;
- duration_ = base::TimeDelta::FromMicroseconds(info_parser.duration() * mult);
-
- cluster_parser_.reset(new WebMClusterParser(
- info_parser.timecode_scale(),
- tracks_parser.audio_track_num(),
- tracks_parser.audio_default_duration(),
- tracks_parser.video_track_num(),
- tracks_parser.video_default_duration()));
+ if (pending_buffers_.empty())
+ return;
- format_context_ = CreateFormatContext(data, size);
+ scoped_refptr<Buffer> buf = pending_buffers_.front();
+ pending_buffers_.pop_front();
- if (!format_context_ || !SetupStreams() || !ParsePendingBuffers()) {
- ChangeState(INIT_ERROR);
- return false;
- }
-
- ChangeState(INITIALIZED);
- return true;
+ ParseInfoAndTracks_Locked(buf->GetData(), buf->GetDataSize());
}
// Filter implementation.
@@ -353,6 +320,7 @@ void ChunkDemuxer::Seek(base::TimeDelta time, const FilterStatusCB& cb) {
base::AutoLock auto_lock(lock_);
if (seek_waits_for_data_) {
+ VLOG(1) << "Seek() : waiting for more data to arrive.";
seek_cb_ = cb;
return;
}
@@ -398,8 +366,8 @@ void ChunkDemuxer::FlushData() {
seek_waits_for_data_ = true;
}
-bool ChunkDemuxer::AddData(const uint8* data, unsigned length) {
- VLOG(1) << "AddData(" << length << ")";
+bool ChunkDemuxer::AppendData(const uint8* data, unsigned length) {
+ VLOG(1) << "AppendData(" << length << ")";
DCHECK(data);
DCHECK_GT(length, 0u);
@@ -416,16 +384,24 @@ bool ChunkDemuxer::AddData(const uint8* data, unsigned length) {
return true;
break;
+ case INITIALIZING:
+ if (!ParseInfoAndTracks_Locked(data, length)) {
+ VLOG(1) << "AppendData(): parsing info & tracks failed";
+ return false;
+ }
+ return true;
+ break;
+
case INITIALIZED:
- if (!ParseAndAddData_Locked(data, length)) {
- VLOG(1) << "AddData(): parsing data failed";
+ if (!ParseAndAppendData_Locked(data, length)) {
+ VLOG(1) << "AppendData(): parsing data failed";
return false;
}
break;
case INIT_ERROR:
case SHUTDOWN:
- VLOG(1) << "AddData(): called in unexpected state " << state_;
+ VLOG(1) << "AppendData(): called in unexpected state " << state_;
return false;
break;
}
@@ -491,6 +467,56 @@ void ChunkDemuxer::ChangeState(State new_state) {
state_ = new_state;
}
+bool ChunkDemuxer::ParseInfoAndTracks_Locked(const uint8* data, int size) {
+ DCHECK(data);
+ DCHECK_GT(size, 0);
+
+ DCHECK_EQ(state_, INITIALIZING);
+
+ const uint8* cur = data;
+ int cur_size = size;
+ WebMInfoParser info_parser;
+ int res = info_parser.Parse(cur, cur_size);
+
+ if (res <= 0) {
+ InitFailed_Locked();
+ return false;
+ }
+
+ cur += res;
+ cur_size -= res;
+
+ WebMTracksParser tracks_parser(info_parser.timecode_scale());
+ res = tracks_parser.Parse(cur, cur_size);
+
+ if (res <= 0) {
+ InitFailed_Locked();
+ return false;
+ }
+
+ double mult = info_parser.timecode_scale() / 1000.0;
+ duration_ = base::TimeDelta::FromMicroseconds(info_parser.duration() * mult);
+
+ cluster_parser_.reset(new WebMClusterParser(
+ info_parser.timecode_scale(),
+ tracks_parser.audio_track_num(),
+ tracks_parser.audio_default_duration(),
+ tracks_parser.video_track_num(),
+ tracks_parser.video_default_duration()));
+
+ format_context_ = CreateFormatContext(data, size);
+
+ if (!format_context_ || !SetupStreams() || !ParsePendingBuffers_Locked()) {
+ InitFailed_Locked();
+ return false;
+ }
+
+ ChangeState(INITIALIZED);
+ init_cb_.Run(PIPELINE_OK);
+ init_cb_.Reset();
+ return true;
+}
+
AVFormatContext* ChunkDemuxer::CreateFormatContext(const uint8* data,
int size) const {
int segment_size = size + sizeof(kEmptyCluster);
@@ -556,7 +582,7 @@ bool ChunkDemuxer::SetupStreams() {
return !no_supported_streams;
}
-bool ChunkDemuxer::ParsePendingBuffers() {
+bool ChunkDemuxer::ParsePendingBuffers_Locked() {
bool had_pending_buffers = !pending_buffers_.empty();
// Handle any buffers that came in between the time the pipeline was
// started and Init() was called.
@@ -564,7 +590,7 @@ bool ChunkDemuxer::ParsePendingBuffers() {
scoped_refptr<media::Buffer> buf = pending_buffers_.front();
pending_buffers_.pop_front();
- if (!ParseAndAddData_Locked(buf->GetData(), buf->GetDataSize())) {
+ if (!ParseAndAppendData_Locked(buf->GetData(), buf->GetDataSize())) {
pending_buffers_.clear();
ChangeState(INIT_ERROR);
return false;
@@ -575,7 +601,7 @@ bool ChunkDemuxer::ParsePendingBuffers() {
return true;
}
-bool ChunkDemuxer::ParseAndAddData_Locked(const uint8* data, int length) {
+bool ChunkDemuxer::ParseAndAppendData_Locked(const uint8* data, int length) {
if (!cluster_parser_.get())
return false;
@@ -586,7 +612,7 @@ bool ChunkDemuxer::ParseAndAddData_Locked(const uint8* data, int length) {
int res = cluster_parser_->Parse(cur, cur_size);
if (res <= 0) {
- VLOG(1) << "ParseAndAddData_Locked() : cluster parsing failed.";
+ VLOG(1) << "ParseAndAppendData_Locked() : cluster parsing failed.";
return false;
}
@@ -616,4 +642,11 @@ bool ChunkDemuxer::ParseAndAddData_Locked(const uint8* data, int length) {
return true;
}
+void ChunkDemuxer::InitFailed_Locked() {
+ ChangeState(INIT_ERROR);
+ PipelineStatusCB cb;
+ std::swap(cb, init_cb_);
+ cb.Run(DEMUXER_ERROR_COULD_NOT_OPEN);
+}
+
} // namespace media
diff --git a/media/filters/chunk_demuxer.h b/media/filters/chunk_demuxer.h
index 7f599e6..8013c4f 100644
--- a/media/filters/chunk_demuxer.h
+++ b/media/filters/chunk_demuxer.h
@@ -24,7 +24,7 @@ class ChunkDemuxer : public Demuxer {
ChunkDemuxer();
virtual ~ChunkDemuxer();
- bool Init(const uint8* data, int size);
+ void Init(PipelineStatusCB cb);
// Filter implementation.
virtual void set_host(FilterHost* filter_host);
@@ -39,12 +39,13 @@ class ChunkDemuxer : public Demuxer {
// Methods used by MediaDataSink
void FlushData();
- bool AddData(const uint8* data, unsigned length);
+ bool AppendData(const uint8* data, unsigned length);
void Shutdown();
private:
enum State {
WAITING_FOR_INIT,
+ INITIALIZING,
INITIALIZED,
INIT_ERROR,
SHUTDOWN,
@@ -52,6 +53,11 @@ class ChunkDemuxer : public Demuxer {
void ChangeState(State new_state);
+ // Parses a buffer that contains an INFO & TRACKS element. Returns false if
+ // the parse fails. This method handles calling & clearing |init_cb_|
+ // before it returns.
+ bool ParseInfoAndTracks_Locked(const uint8* data, int size);
+
// Generates an AVFormatContext for the INFO & TRACKS elements contained
// in |data|. Returns NULL if parsing |data| fails.
AVFormatContext* CreateFormatContext(const uint8* data, int size) const;
@@ -63,15 +69,19 @@ class ChunkDemuxer : public Demuxer {
// Parse all the buffers in |pending_buffers_|. Returns false if parsing one
// of the buffers fails.
- bool ParsePendingBuffers();
+ bool ParsePendingBuffers_Locked();
+
+ // Parse a buffer that was passed to AppendData(). |data| is expected to
+ // contain one or more WebM Clusters. Returns false if parsing the data fails.
+ bool ParseAndAppendData_Locked(const uint8* data, int length);
- // Parse a buffer that was passed to AddData(). |data| is expected to contain
- // one or more WebM Clusters. Returns false if parsing the data fails.
- bool ParseAndAddData_Locked(const uint8* data, int length);
+ // Called when initialization fails. Handles calling & clearing init_cb_.
+ void InitFailed_Locked();
base::Lock lock_;
State state_;
+ PipelineStatusCB init_cb_;
FilterStatusCB seek_cb_;
scoped_refptr<ChunkDemuxerStream> audio_;
diff --git a/media/filters/chunk_demuxer_factory.cc b/media/filters/chunk_demuxer_factory.cc
index 4cb81ce..a354b39 100644
--- a/media/filters/chunk_demuxer_factory.cc
+++ b/media/filters/chunk_demuxer_factory.cc
@@ -4,11 +4,32 @@
#include "media/filters/chunk_demuxer_factory.h"
+#include "base/bind.h"
#include "base/message_loop.h"
#include "media/filters/chunk_demuxer.h"
namespace media {
+static void DoInitDone(DemuxerFactory::BuildCallback* cb,
+ const scoped_refptr<Demuxer>& demuxer,
+ PipelineStatus status) {
+ scoped_ptr<DemuxerFactory::BuildCallback> callback(cb);
+ if (status != PIPELINE_OK) {
+ callback->Run(status, static_cast<Demuxer*>(NULL));
+ return;
+ }
+
+ callback->Run(status, demuxer);
+}
+
+static void InitDone(MessageLoop* message_loop,
+ DemuxerFactory::BuildCallback* cb,
+ const scoped_refptr<Demuxer>& demuxer,
+ PipelineStatus status) {
+ message_loop->PostTask(FROM_HERE,
+ NewRunnableFunction(&DoInitDone, cb, demuxer, status));
+}
+
MediaDataSink::MediaDataSink(const scoped_refptr<ChunkDemuxer>& demuxer)
: demuxer_(demuxer) {
}
@@ -19,8 +40,8 @@ void MediaDataSink::Flush() {
demuxer_->FlushData();
}
-bool MediaDataSink::AddData(const uint8* data, unsigned length) {
- return demuxer_->AddData(data, length);
+bool MediaDataSink::AppendData(const uint8* data, unsigned length) {
+ return demuxer_->AppendData(data, length);
}
void MediaDataSink::Shutdown() {
@@ -29,107 +50,7 @@ void MediaDataSink::Shutdown() {
const char ChunkDemuxerFactory::kURLPrefix[] = "x-media-chunks:";
-class ChunkDemuxerFactory::BuildState
- : public base::RefCountedThreadSafe<BuildState> {
- public:
- static const int64 kMaxInfoSize = 32678;
-
- BuildState(const std::string& url, BuildCallback* cb,
- const scoped_refptr<ChunkDemuxer>& demuxer)
- : url_(url),
- cb_(cb),
- demuxer_(demuxer),
- read_buffer_(NULL),
- message_loop_(MessageLoop::current()) {
- AddRef();
- }
-
- virtual ~BuildState() {}
-
- void OnBuildDone(PipelineStatus status, DataSource* data_source) {
- message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &BuildState::DoBuildDone,
- status, scoped_refptr<DataSource>(data_source)));
- }
-
- void DoBuildDone(PipelineStatus status, DataSource* data_source) {
- if (status != PIPELINE_OK) {
- cb_->Run(status, static_cast<Demuxer*>(NULL));
- Release();
- return;
- }
-
- data_source_ = data_source;
-
- int64 size = 0;
-
- if (!data_source_->GetSize(&size) || size >= kMaxInfoSize) {
- RunCallbackAndStop(DEMUXER_ERROR_COULD_NOT_OPEN);
- return;
- }
-
- DCHECK(!read_buffer_.get());
- read_buffer_.reset(new uint8[size]);
- data_source_->Read(0, size, read_buffer_.get(),
- NewCallback(this, &BuildState::OnReadDone));
- }
-
- void OnReadDone(size_t size) {
- message_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this,
- &BuildState::DoReadDone,
- size));
- }
-
- void DoReadDone(size_t size) {
- if (size == DataSource::kReadError) {
- RunCallbackAndStop(PIPELINE_ERROR_READ);
- return;
- }
-
- if (!demuxer_->Init(read_buffer_.get(), size)) {
- RunCallbackAndStop(DEMUXER_ERROR_COULD_NOT_OPEN);
- return;
- }
-
- RunCallbackAndStop(PIPELINE_OK);
- }
-
- void RunCallbackAndStop(PipelineStatus status) {
- scoped_refptr<Demuxer> demuxer;
-
- if (status == PIPELINE_OK)
- demuxer = demuxer_.get();
-
- cb_->Run(status, demuxer.get());
- data_source_->Stop(NewCallback(this, &BuildState::OnStopDone));
- }
-
- void OnStopDone() {
- message_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this,
- &BuildState::DoStopDone));
- }
-
- void DoStopDone() { Release(); }
-
- private:
- std::string url_;
- scoped_ptr<BuildCallback> cb_;
- scoped_refptr<ChunkDemuxer> demuxer_;
-
- scoped_refptr<DataSource> data_source_;
- scoped_array<uint8> read_buffer_;
- MessageLoop* message_loop_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(BuildState);
-};
-
-ChunkDemuxerFactory::ChunkDemuxerFactory(
- DataSourceFactory* data_source_factory)
- : data_source_factory_(data_source_factory) {
-}
+ChunkDemuxerFactory::ChunkDemuxerFactory() {}
ChunkDemuxerFactory::~ChunkDemuxerFactory() {}
@@ -149,17 +70,15 @@ void ChunkDemuxerFactory::Build(const std::string& url, BuildCallback* cb) {
return;
}
- std::string info_url = url.substr(strlen(kURLPrefix));
-
- data_source_factory_->Build(
- info_url,
- NewCallback(new BuildState(info_url, cb, demuxer_),
- &ChunkDemuxerFactory::BuildState::OnBuildDone));
+ // Call Init() on demuxer. Note that ownership is being passed to the
+ // callback here.
+ demuxer_->Init(base::Bind(&InitDone, MessageLoop::current(), cb,
+ scoped_refptr<Demuxer>(demuxer_.get())));
demuxer_ = NULL;
}
DemuxerFactory* ChunkDemuxerFactory::Clone() const {
- return new ChunkDemuxerFactory(data_source_factory_->Clone());
+ return new ChunkDemuxerFactory();
}
} // namespace media
diff --git a/media/filters/chunk_demuxer_factory.h b/media/filters/chunk_demuxer_factory.h
index df6f742..614820e 100644
--- a/media/filters/chunk_demuxer_factory.h
+++ b/media/filters/chunk_demuxer_factory.h
@@ -32,7 +32,7 @@ class MediaDataSink {
void Flush();
// Sends media data to the demuxer. Returns true if the data is valid.
- bool AddData(const uint8* data, unsigned length);
+ bool AppendData(const uint8* data, unsigned length);
// Signals that playback is shutting down and further AddData() calls
// should fail. This also cancels pending Read()s on DemuxerStreams.
@@ -46,7 +46,7 @@ class MediaDataSink {
class ChunkDemuxerFactory : public DemuxerFactory {
public:
// Takes a reference to |demuxer_factory|.
- ChunkDemuxerFactory(DataSourceFactory* data_source_factory);
+ ChunkDemuxerFactory();
virtual ~ChunkDemuxerFactory();
bool IsUrlSupported(const std::string& url) const;
@@ -58,12 +58,9 @@ class ChunkDemuxerFactory : public DemuxerFactory {
private:
static const char kURLPrefix[];
- class BuildState;
-
- scoped_ptr<DataSourceFactory> data_source_factory_;
scoped_refptr<ChunkDemuxer> demuxer_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerFactory);
+ DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerFactory);
};
} // namespace media
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc
index 83795e5..695cee3 100644
--- a/media/filters/chunk_demuxer_unittest.cc
+++ b/media/filters/chunk_demuxer_unittest.cc
@@ -134,7 +134,7 @@ class ChunkDemuxerTest : public testing::Test{
}
}
- void InitDemuxer(bool has_audio, bool has_video) {
+ void AppendInfoTracks(bool has_audio, bool has_video) {
EXPECT_CALL(mock_ffmpeg_, AVOpenInputFile(_, _, NULL, 0, NULL))
.WillOnce(DoAll(SetArgumentPointee<0>(&format_context_),
Return(0)));
@@ -153,8 +153,27 @@ class ChunkDemuxerTest : public testing::Test{
SetupAVFormatContext(has_audio, has_video);
- EXPECT_EQ(demuxer_->Init(info_tracks.get(), info_tracks_size),
- has_audio || has_video);
+ demuxer_->AppendData(info_tracks.get(), info_tracks_size);
+ }
+
+ static void InitDoneCalled(bool* was_called, PipelineStatus expectedStatus,
+ PipelineStatus status) {
+ EXPECT_EQ(status, expectedStatus);
+ *was_called = true;
+ }
+
+ void InitDemuxer(bool has_audio, bool has_video) {
+ bool init_done_called = false;
+ PipelineStatus expectedStatus =
+ (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN;
+ demuxer_->Init(base::Bind(&ChunkDemuxerTest::InitDoneCalled,
+ &init_done_called, expectedStatus));
+
+ EXPECT_FALSE(init_done_called);
+
+ AppendInfoTracks(has_audio, has_video);
+
+ EXPECT_TRUE(init_done_called);
}
void ShutdownDemuxer() {
@@ -240,7 +259,7 @@ TEST_F(ChunkDemuxerTest, TestShutdownBeforeFirstSeekCompletes) {
// Test that Seek() completes successfully when the first cluster
// arrives.
-TEST_F(ChunkDemuxerTest, TestAddDataAfterSeek) {
+TEST_F(ChunkDemuxerTest, TestAppendDataAfterSeek) {
InitDemuxer(true, true);
InSequence s;
@@ -259,23 +278,25 @@ TEST_F(ChunkDemuxerTest, TestAddDataAfterSeek) {
Checkpoint(1);
- EXPECT_TRUE(demuxer_->AddData(cluster->data(), cluster->size()));
+ EXPECT_TRUE(demuxer_->AppendData(cluster->data(), cluster->size()));
Checkpoint(2);
}
-// Test the case where AddData() is called before Init(). This can happen
+// Test the case where AppendData() is called before Init(). This can happen
// when JavaScript starts sending data before the pipeline is completely
// initialized.
-TEST_F(ChunkDemuxerTest, TestAddDataBeforeInit) {
+TEST_F(ChunkDemuxerTest, TestAppendDataBeforeInit) {
+ AppendInfoTracks(true, true);
+
ClusterBuilder cb;
cb.SetClusterTimecode(0);
AddSimpleBlock(&cb, kVideoTrackNum, 0);
scoped_ptr<Cluster> cluster(cb.Finish());
- EXPECT_TRUE(demuxer_->AddData(cluster->data(), cluster->size()));
+ EXPECT_TRUE(demuxer_->AppendData(cluster->data(), cluster->size()));
- InitDemuxer(true, true);
+ demuxer_->Init(NewExpectedStatusCB(PIPELINE_OK));
demuxer_->Seek(base::TimeDelta::FromSeconds(0),
NewExpectedStatusCB(PIPELINE_OK));
@@ -313,7 +334,7 @@ TEST_F(ChunkDemuxerTest, TestRead) {
AddSimpleBlock(&cb, kVideoTrackNum, 123);
scoped_ptr<Cluster> cluster(cb.Finish());
- EXPECT_TRUE(demuxer_->AddData(cluster->data(), cluster->size()));
+ EXPECT_TRUE(demuxer_->AppendData(cluster->data(), cluster->size()));
EXPECT_TRUE(audio_read_done);
EXPECT_TRUE(video_read_done);
@@ -331,7 +352,7 @@ TEST_F(ChunkDemuxerTest, TestOutOfOrderClusters) {
AddSimpleBlock(&cb, kVideoTrackNum, 43);
scoped_ptr<Cluster> clusterA(cb.Finish());
- EXPECT_TRUE(demuxer_->AddData(clusterA->data(), clusterA->size()));
+ EXPECT_TRUE(demuxer_->AppendData(clusterA->data(), clusterA->size()));
// Cluster B starts before clusterA and has data
// that overlaps.
@@ -342,9 +363,9 @@ TEST_F(ChunkDemuxerTest, TestOutOfOrderClusters) {
AddSimpleBlock(&cb, kVideoTrackNum, 40);
scoped_ptr<Cluster> clusterB(cb.Finish());
- // Make sure that AddData() fails because this cluster data
+ // Make sure that AppendData() fails because this cluster data
// is before previous data.
- EXPECT_FALSE(demuxer_->AddData(clusterB->data(), clusterB->size()));
+ EXPECT_FALSE(demuxer_->AppendData(clusterB->data(), clusterB->size()));
// Cluster C starts after clusterA.
cb.SetClusterTimecode(56);
@@ -355,15 +376,15 @@ TEST_F(ChunkDemuxerTest, TestOutOfOrderClusters) {
scoped_ptr<Cluster> clusterC(cb.Finish());
// Verify that clusterC is accepted.
- EXPECT_TRUE(demuxer_->AddData(clusterC->data(), clusterC->size()));
+ EXPECT_TRUE(demuxer_->AppendData(clusterC->data(), clusterC->size()));
// Flush and try clusterB again.
demuxer_->FlushData();
- EXPECT_TRUE(demuxer_->AddData(clusterB->data(), clusterB->size()));
+ EXPECT_TRUE(demuxer_->AppendData(clusterB->data(), clusterB->size()));
// Following that with clusterC should work too since it doesn't
// overlap with clusterB.
- EXPECT_TRUE(demuxer_->AddData(clusterC->data(), clusterC->size()));
+ EXPECT_TRUE(demuxer_->AppendData(clusterC->data(), clusterC->size()));
}
TEST_F(ChunkDemuxerTest, TestInvalidBlockSequences) {
@@ -380,7 +401,7 @@ TEST_F(ChunkDemuxerTest, TestInvalidBlockSequences) {
AddSimpleBlock(&cb, kVideoTrackNum, 15);
scoped_ptr<Cluster> clusterA(cb.Finish());
- EXPECT_FALSE(demuxer_->AddData(clusterA->data(), clusterA->size()));
+ EXPECT_FALSE(demuxer_->AppendData(clusterA->data(), clusterA->size()));
// Test timecodes going backwards before cluster timecode.
cb.SetClusterTimecode(5);
@@ -390,7 +411,7 @@ TEST_F(ChunkDemuxerTest, TestInvalidBlockSequences) {
AddSimpleBlock(&cb, kVideoTrackNum, 3);
scoped_ptr<Cluster> clusterB(cb.Finish());
- EXPECT_FALSE(demuxer_->AddData(clusterB->data(), clusterB->size()));
+ EXPECT_FALSE(demuxer_->AppendData(clusterB->data(), clusterB->size()));
// Test strict monotonic increasing timestamps on a per stream
// basis.
@@ -401,7 +422,7 @@ TEST_F(ChunkDemuxerTest, TestInvalidBlockSequences) {
AddSimpleBlock(&cb, kVideoTrackNum, 7);
scoped_ptr<Cluster> clusterC(cb.Finish());
- EXPECT_FALSE(demuxer_->AddData(clusterC->data(), clusterC->size()));
+ EXPECT_FALSE(demuxer_->AppendData(clusterC->data(), clusterC->size()));
// Test strict monotonic increasing timestamps on a per stream
// basis across clusters.
@@ -410,14 +431,27 @@ TEST_F(ChunkDemuxerTest, TestInvalidBlockSequences) {
AddSimpleBlock(&cb, kVideoTrackNum, 5);
scoped_ptr<Cluster> clusterD(cb.Finish());
- EXPECT_TRUE(demuxer_->AddData(clusterD->data(), clusterD->size()));
+ EXPECT_TRUE(demuxer_->AppendData(clusterD->data(), clusterD->size()));
cb.SetClusterTimecode(5);
AddSimpleBlock(&cb, kAudioTrackNum, 5);
AddSimpleBlock(&cb, kVideoTrackNum, 7);
scoped_ptr<Cluster> clusterE(cb.Finish());
- EXPECT_FALSE(demuxer_->AddData(clusterE->data(), clusterE->size()));
+ EXPECT_FALSE(demuxer_->AppendData(clusterE->data(), clusterE->size()));
+}
+
+// Test the case where a cluster is passed to AppendData() before
+// INFO & TRACKS data.
+TEST_F(ChunkDemuxerTest, TestClusterBeforeInfoTracks) {
+ demuxer_->Init(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
+
+ ClusterBuilder cb;
+ cb.SetClusterTimecode(0);
+ AddSimpleBlock(&cb, kVideoTrackNum, 0);
+ scoped_ptr<Cluster> cluster(cb.Finish());
+
+ EXPECT_FALSE(demuxer_->AppendData(cluster->data(), cluster->size()));
}
} // namespace media