Skip to content
Browse files

Move Demuxer::set_host() to Initialize().

BUG=111585

Review URL: https://chromiumcodereview.appspot.com/9968117

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@130842 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information...
1 parent 91b01b8 commit d09ef258f1ffc7f67810359cca9f40badce37466 scherkus@chromium.org committed Apr 5, 2012
View
8 media/base/demuxer.cc
@@ -10,16 +10,10 @@ namespace media {
DemuxerHost::~DemuxerHost() {}
-Demuxer::Demuxer() : host_(NULL) {}
+Demuxer::Demuxer() {}
Demuxer::~Demuxer() {}
-void Demuxer::set_host(DemuxerHost* host) {
- DCHECK(host);
- DCHECK(!host_);
- host_ = host;
-}
-
void Demuxer::SetPlaybackRate(float playback_rate) {}
void Demuxer::Seek(base::TimeDelta time, const PipelineStatusCB& status_cb) {
View
25 media/base/demuxer.h
@@ -34,22 +34,16 @@ class MEDIA_EXPORT DemuxerHost : public DataSourceHost {
virtual void OnDemuxerError(PipelineStatus error) = 0;
};
-class MEDIA_EXPORT Demuxer
- : public base::RefCountedThreadSafe<Demuxer> {
+class MEDIA_EXPORT Demuxer : public base::RefCountedThreadSafe<Demuxer> {
public:
Demuxer();
- // Sets the private member |host_|. This is the first method called by
- // the DemuxerHost after a demuxer is created. The host holds a strong
- // reference to the demuxer. The reference held by the host is guaranteed
- // to be released before the host object is destroyed by the pipeline.
- virtual void set_host(DemuxerHost* host);
-
// Completes initialization of the demuxer.
//
- // TODO(scherkus): pass in DemuxerHost here instead of using set_host(),
- // see http://crbug.com/111585
- virtual void Initialize(const PipelineStatusCB& status_cb) = 0;
+ // The demuxer does not own |host| as it is guaranteed to outlive the
+ // lifetime of the demuxer. Don't delete it!
+ virtual void Initialize(DemuxerHost* host,
+ const PipelineStatusCB& status_cb) = 0;
// The pipeline playback rate has been changed. Demuxers may implement this
// method if they need to respond to this call.
@@ -90,19 +84,10 @@ class MEDIA_EXPORT Demuxer
virtual bool IsSeekable() = 0;
protected:
- // Only allow derived objects access to the DemuxerHost. This is
- // kept out of the public interface because demuxers need to be
- // aware of all calls made to the host object so they can insure
- // the state presented to the host is always consistent with its own
- // state.
- DemuxerHost* host() { return host_; }
-
friend class base::RefCountedThreadSafe<Demuxer>;
virtual ~Demuxer();
private:
- DemuxerHost* host_;
-
DISALLOW_COPY_AND_ASSIGN(Demuxer);
};
View
27 media/base/mock_filters.cc
@@ -38,35 +38,10 @@ void MockDataSource::SetTotalAndBufferedBytes(int64 total_bytes,
buffered_bytes_ = buffered_bytes;
}
-MockDemuxer::MockDemuxer()
- : total_bytes_(-1), buffered_bytes_(-1), duration_() {
- EXPECT_CALL(*this, GetBitrate()).WillRepeatedly(Return(0));
- EXPECT_CALL(*this, IsLocalSource()).WillRepeatedly(Return(false));
- EXPECT_CALL(*this, IsSeekable()).WillRepeatedly(Return(false));
-}
+MockDemuxer::MockDemuxer() {}
MockDemuxer::~MockDemuxer() {}
-void MockDemuxer::set_host(DemuxerHost* demuxer_host) {
- Demuxer::set_host(demuxer_host);
-
- if (total_bytes_ > 0)
- host()->SetTotalBytes(total_bytes_);
-
- if (buffered_bytes_ > 0)
- host()->SetBufferedBytes(buffered_bytes_);
-
- if (duration_.InMilliseconds() > 0)
- host()->SetDuration(duration_);
-}
-
-void MockDemuxer::SetTotalAndBufferedBytesAndDuration(
- int64 total_bytes, int64 buffered_bytes, const base::TimeDelta& duration) {
- total_bytes_ = total_bytes;
- buffered_bytes_ = buffered_bytes;
- duration_ = duration;
-}
-
MockDemuxerStream::MockDemuxerStream() {}
MockDemuxerStream::~MockDemuxerStream() {}
View
27 media/base/mock_filters.h
@@ -105,35 +105,22 @@ class MockDemuxer : public Demuxer {
public:
MockDemuxer();
- MOCK_METHOD1(Initialize, void(const PipelineStatusCB& cb));
- virtual void set_host(DemuxerHost* demuxer_host);
- MOCK_METHOD1(Stop, void(const base::Closure& callback));
+ // Demuxer implementation.
+ MOCK_METHOD2(Initialize, void(DemuxerHost* host, const PipelineStatusCB& cb));
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
MOCK_METHOD2(Seek, void(base::TimeDelta time, const PipelineStatusCB& cb));
+ MOCK_METHOD1(Stop, void(const base::Closure& callback));
MOCK_METHOD0(OnAudioRendererDisabled, void());
+ MOCK_METHOD1(GetStream, scoped_refptr<DemuxerStream>(DemuxerStream::Type));
+ MOCK_CONST_METHOD0(GetStartTime, base::TimeDelta());
MOCK_METHOD0(GetBitrate, int());
MOCK_METHOD0(IsLocalSource, bool());
MOCK_METHOD0(IsSeekable, bool());
- // Demuxer implementation.
- MOCK_METHOD2(Initialize, void(DataSource* data_source,
- const base::Closure& callback));
- MOCK_METHOD1(GetStream, scoped_refptr<DemuxerStream>(DemuxerStream::Type));
- MOCK_CONST_METHOD0(GetStartTime, base::TimeDelta());
-
- // Sets the TotalBytes, BufferedBytes, & Duration values to be sent to host()
- // when set_host() is called.
- void SetTotalAndBufferedBytesAndDuration(
- int64 total_bytes, int64 buffered_bytes, const base::TimeDelta& duration);
-
protected:
virtual ~MockDemuxer();
private:
- int64 total_bytes_;
- int64 buffered_bytes_;
- base::TimeDelta duration_;
-
DISALLOW_COPY_AND_ASSIGN(MockDemuxer);
};
@@ -299,10 +286,6 @@ void RunPipelineStatusCB4(::testing::Unused, const PipelineStatusCB& status_cb,
// provided filter. Can be used when mocking the Stop() method.
void RunStopFilterCallback(const base::Closure& closure);
-ACTION_P(RunPipelineStatusCBWithError, error) {
- arg0.Run(error);
-}
-
// Helper gmock action that calls SetError() on behalf of the provided filter.
ACTION_P2(SetError, filter, error) {
filter->host()->SetError(error);
View
3 media/base/pipeline.cc
@@ -1091,8 +1091,7 @@ void Pipeline::InitializeDemuxer() {
return;
}
- demuxer_->set_host(this);
- demuxer_->Initialize(base::Bind(&Pipeline::OnDemuxerInitialized, this));
+ demuxer_->Initialize(this, base::Bind(&Pipeline::OnDemuxerInitialized, this));
}
void Pipeline::OnDemuxerInitialized(PipelineStatus status) {
View
84 media/base/pipeline_unittest.cc
@@ -20,9 +20,9 @@
using ::testing::_;
using ::testing::DeleteArg;
+using ::testing::DoAll;
using ::testing::InSequence;
using ::testing::Invoke;
-using ::testing::InvokeArgument;
using ::testing::Mock;
using ::testing::NotNull;
using ::testing::Return;
@@ -32,11 +32,22 @@ using ::testing::WithArg;
namespace media {
-// Total bytes of the data source.
+// Demuxer properties.
static const int kTotalBytes = 1024;
-
-// Buffered bytes of the data source.
static const int kBufferedBytes = 1024;
+static const int kBitrate = 1234;
+static const bool kLocalSource = false;
+static const bool kSeekable = true;
+
+ACTION_P(InitializeDemuxerWithError, error) {
+ arg1.Run(error);
+}
+
+ACTION_P(SetDemuxerProperties, duration) {
+ arg0->SetTotalBytes(kTotalBytes);
+ arg0->SetBufferedBytes(kBufferedBytes);
+ arg0->SetDuration(duration);
+}
// Used for setting expectations on pipeline callbacks. Using a StrictMock
// also lets us test for missing callbacks.
@@ -67,7 +78,7 @@ class PipelineTest : public ::testing::Test {
: pipeline_(new Pipeline(&message_loop_, new MediaLog())) {
mocks_.reset(new MockFilterCollection());
- // InitializeDemuxer adds overriding expectations for expected non-NULL
+ // InitializeDemuxer() adds overriding expectations for expected non-NULL
// streams.
DemuxerStream* null_pointer = NULL;
EXPECT_CALL(*mocks_->demuxer(), GetStream(_))
@@ -97,16 +108,23 @@ class PipelineTest : public ::testing::Test {
typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector;
void InitializeDemuxer(MockDemuxerStreamVector* streams,
const base::TimeDelta& duration) {
- EXPECT_CALL(*mocks_->demuxer(), Initialize(_))
- .WillOnce(Invoke(&RunPipelineStatusCB));
- mocks_->demuxer()->SetTotalAndBufferedBytesAndDuration(
- kTotalBytes, kBufferedBytes, duration);
+ EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _))
+ .WillOnce(DoAll(SetDemuxerProperties(duration),
+ Invoke(&RunPipelineStatusCB2)));
EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(0.0f));
EXPECT_CALL(*mocks_->demuxer(), Seek(mocks_->demuxer()->GetStartTime(), _))
.WillOnce(Invoke(&RunPipelineStatusCB2));
EXPECT_CALL(*mocks_->demuxer(), Stop(_))
.WillOnce(Invoke(&RunStopFilterCallback));
+ // Demuxer properties.
+ EXPECT_CALL(*mocks_->demuxer(), GetBitrate())
+ .WillRepeatedly(Return(kBitrate));
+ EXPECT_CALL(*mocks_->demuxer(), IsLocalSource())
+ .WillRepeatedly(Return(kLocalSource));
+ EXPECT_CALL(*mocks_->demuxer(), IsSeekable())
+ .WillRepeatedly(Return(kSeekable));
+
// Configure the demuxer to return the streams.
for (size_t i = 0; i < streams->size(); ++i) {
scoped_refptr<DemuxerStream> stream((*streams)[i]);
@@ -115,6 +133,11 @@ class PipelineTest : public ::testing::Test {
}
}
+ void InitializeDemuxer(MockDemuxerStreamVector* streams) {
+ // Initialize with a default non-zero duration.
+ InitializeDemuxer(streams, base::TimeDelta::FromSeconds(10));
+ }
+
StrictMock<MockDemuxerStream>* CreateStream(DemuxerStream::Type type) {
StrictMock<MockDemuxerStream>* stream =
new StrictMock<MockDemuxerStream>();
@@ -281,7 +304,7 @@ TEST_F(PipelineTest, NotStarted) {
TEST_F(PipelineTest, NeverInitializes) {
// Don't execute the callback passed into Initialize().
- EXPECT_CALL(*mocks_->demuxer(), Initialize(_));
+ EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _));
EXPECT_CALL(*mocks_->demuxer(), Stop(_))
.WillOnce(Invoke(&RunStopFilterCallback));
@@ -322,9 +345,8 @@ TEST_F(PipelineTest, RequiredFilterMissing) {
}
TEST_F(PipelineTest, URLNotFound) {
- EXPECT_CALL(*mocks_->demuxer(), Initialize(_))
- .WillOnce(RunPipelineStatusCBWithError(
- PIPELINE_ERROR_URL_NOT_FOUND));
+ EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _))
+ .WillOnce(InitializeDemuxerWithError(PIPELINE_ERROR_URL_NOT_FOUND));
EXPECT_CALL(*mocks_->demuxer(), Stop(_))
.WillOnce(Invoke(&RunStopFilterCallback));
@@ -333,8 +355,8 @@ TEST_F(PipelineTest, URLNotFound) {
}
TEST_F(PipelineTest, NoStreams) {
- EXPECT_CALL(*mocks_->demuxer(), Initialize(_))
- .WillOnce(Invoke(&RunPipelineStatusCB));
+ EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _))
+ .WillOnce(Invoke(&RunPipelineStatusCB2));
EXPECT_CALL(*mocks_->demuxer(), Stop(_))
.WillOnce(Invoke(&RunStopFilterCallback));
@@ -347,7 +369,7 @@ TEST_F(PipelineTest, AudioStream) {
MockDemuxerStreamVector streams;
streams.push_back(audio_stream());
- InitializeDemuxer(&streams, base::TimeDelta());
+ InitializeDemuxer(&streams);
InitializeAudioDecoder(audio_stream());
InitializeAudioRenderer();
@@ -362,7 +384,7 @@ TEST_F(PipelineTest, VideoStream) {
MockDemuxerStreamVector streams;
streams.push_back(video_stream());
- InitializeDemuxer(&streams, base::TimeDelta());
+ InitializeDemuxer(&streams);
InitializeVideoDecoder(video_stream());
InitializeVideoRenderer();
@@ -379,7 +401,7 @@ TEST_F(PipelineTest, AudioVideoStream) {
streams.push_back(audio_stream());
streams.push_back(video_stream());
- InitializeDemuxer(&streams, base::TimeDelta());
+ InitializeDemuxer(&streams);
InitializeAudioDecoder(audio_stream());
InitializeAudioRenderer();
InitializeVideoDecoder(video_stream());
@@ -418,7 +440,7 @@ TEST_F(PipelineTest, SetVolume) {
MockDemuxerStreamVector streams;
streams.push_back(audio_stream());
- InitializeDemuxer(&streams, base::TimeDelta());
+ InitializeDemuxer(&streams);
InitializeAudioDecoder(audio_stream());
InitializeAudioRenderer();
@@ -522,7 +544,7 @@ TEST_F(PipelineTest, DisableAudioRenderer) {
streams.push_back(audio_stream());
streams.push_back(video_stream());
- InitializeDemuxer(&streams, base::TimeDelta());
+ InitializeDemuxer(&streams);
InitializeAudioDecoder(audio_stream());
InitializeAudioRenderer();
InitializeVideoDecoder(video_stream());
@@ -559,7 +581,7 @@ TEST_F(PipelineTest, DisableAudioRendererDuringInit) {
streams.push_back(audio_stream());
streams.push_back(video_stream());
- InitializeDemuxer(&streams, base::TimeDelta());
+ InitializeDemuxer(&streams);
InitializeAudioDecoder(audio_stream());
InitializeAudioRenderer(true);
InitializeVideoDecoder(video_stream());
@@ -592,7 +614,7 @@ TEST_F(PipelineTest, EndedCallback) {
streams.push_back(audio_stream());
streams.push_back(video_stream());
- InitializeDemuxer(&streams, base::TimeDelta());
+ InitializeDemuxer(&streams);
InitializeAudioDecoder(audio_stream());
InitializeAudioRenderer();
InitializeVideoDecoder(video_stream());
@@ -814,6 +836,24 @@ TEST_F(PipelineTest, StartTimeIsNonZero) {
EXPECT_EQ(kStartTime, pipeline_->GetCurrentTime());
}
+TEST_F(PipelineTest, DemuxerProperties) {
+ CreateAudioStream();
+ CreateVideoStream();
+ MockDemuxerStreamVector streams;
+ streams.push_back(audio_stream());
+ streams.push_back(video_stream());
+
+ InitializeDemuxer(&streams);
+ InitializeAudioDecoder(audio_stream());
+ InitializeAudioRenderer();
+ InitializeVideoDecoder(video_stream());
+ InitializeVideoRenderer();
+ InitializePipeline(PIPELINE_OK);
+
+ EXPECT_EQ(kLocalSource, pipeline_->IsLocalSource());
+ EXPECT_EQ(!kSeekable, pipeline_->IsStreaming());
+}
+
class FlexibleCallbackRunner : public base::DelegateSimpleThread::Delegate {
public:
FlexibleCallbackRunner(base::TimeDelta delay, PipelineStatus status,
View
17 media/filters/chunk_demuxer.cc
@@ -333,6 +333,7 @@ void ChunkDemuxerStream::CreateReadDoneClosures_Locked(ClosureQueue* closures) {
ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client)
: state_(WAITING_FOR_INIT),
+ host_(NULL),
client_(client),
buffered_bytes_(0),
seek_waits_for_data_(true) {
@@ -343,11 +344,13 @@ ChunkDemuxer::~ChunkDemuxer() {
DCHECK_NE(state_, INITIALIZED);
}
-void ChunkDemuxer::Initialize(const PipelineStatusCB& cb) {
+void ChunkDemuxer::Initialize(DemuxerHost* host,
+ const PipelineStatusCB& cb) {
DVLOG(1) << "Init()";
{
base::AutoLock auto_lock(lock_);
DCHECK_EQ(state_, WAITING_FOR_INIT);
+ host_ = host;
ChangeState_Locked(INITIALIZING);
init_cb_ = cb;
@@ -537,13 +540,13 @@ bool ChunkDemuxer::AppendData(const uint8* data, size_t length) {
}
// Notify the host of 'network activity' because we got data.
- host()->SetBufferedBytes(buffered_bytes);
+ host_->SetBufferedBytes(buffered_bytes);
if (buffered_ts.InSeconds() >= 0) {
- host()->SetBufferedTime(buffered_ts);
+ host_->SetBufferedTime(buffered_ts);
}
- host()->SetNetworkActivity(true);
+ host_->SetNetworkActivity(true);
if (!cb.is_null())
cb.Run(PIPELINE_OK);
@@ -649,7 +652,7 @@ void ChunkDemuxer::ReportError_Locked(PipelineStatus error) {
}
base::AutoUnlock auto_unlock(lock_);
- host()->OnDemuxerError(error);
+ host_->OnDemuxerError(error);
}
void ChunkDemuxer::OnStreamParserInitDone(bool success,
@@ -662,8 +665,8 @@ void ChunkDemuxer::OnStreamParserInitDone(bool success,
}
duration_ = duration;
- host()->SetDuration(duration_);
- host()->SetCurrentReadPosition(0);
+ host_->SetDuration(duration_);
+ host_->SetCurrentReadPosition(0);
ChangeState_Locked(INITIALIZED);
PipelineStatusCB cb;
View
4 media/filters/chunk_demuxer.h
@@ -26,7 +26,8 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer, public StreamParserHost {
virtual ~ChunkDemuxer();
// Demuxer implementation.
- virtual void Initialize(const PipelineStatusCB& cb) OVERRIDE;
+ virtual void Initialize(DemuxerHost* host,
+ const PipelineStatusCB& cb) OVERRIDE;
virtual void Stop(const base::Closure& callback) OVERRIDE;
virtual void Seek(base::TimeDelta time, const PipelineStatusCB& cb) OVERRIDE;
virtual void OnAudioRendererDisabled() OVERRIDE;
@@ -74,6 +75,7 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer, public StreamParserHost {
base::Lock lock_;
State state_;
+ DemuxerHost* host_;
ChunkDemuxerClient* client_;
PipelineStatusCB init_cb_;
PipelineStatusCB seek_cb_;
View
50 media/filters/chunk_demuxer_unittest.cc
@@ -90,7 +90,6 @@ class ChunkDemuxerTest : public testing::Test {
ChunkDemuxerTest()
: client_(new MockChunkDemuxerClient()),
demuxer_(new ChunkDemuxer(client_.get())) {
- demuxer_->set_host(&mock_demuxer_host_);
}
virtual ~ChunkDemuxerTest() {
@@ -161,9 +160,9 @@ class ChunkDemuxerTest : public testing::Test {
}
bool AppendData(const uint8* data, size_t length) {
- EXPECT_CALL(mock_demuxer_host_, SetBufferedBytes(_)).Times(AnyNumber());
- EXPECT_CALL(mock_demuxer_host_, SetBufferedTime(_)).Times(AnyNumber());
- EXPECT_CALL(mock_demuxer_host_, SetNetworkActivity(true))
+ EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber());
+ EXPECT_CALL(host_, SetBufferedTime(_)).Times(AnyNumber());
+ EXPECT_CALL(host_, SetNetworkActivity(true))
.Times(AnyNumber());
return demuxer_->AppendData(data, length);
}
@@ -202,8 +201,8 @@ class ChunkDemuxerTest : public testing::Test {
PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration,
PipelineStatus expected_status) {
if (expected_status == PIPELINE_OK) {
- EXPECT_CALL(mock_demuxer_host_, SetDuration(expected_duration));
- EXPECT_CALL(mock_demuxer_host_, SetCurrentReadPosition(_));
+ EXPECT_CALL(host_, SetDuration(expected_duration));
+ EXPECT_CALL(host_, SetCurrentReadPosition(_));
}
return base::Bind(&ChunkDemuxerTest::InitDoneCalled,
@@ -217,8 +216,8 @@ class ChunkDemuxerTest : public testing::Test {
(has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN;
EXPECT_CALL(*client_, DemuxerOpened(_));
- demuxer_->Initialize(CreateInitDoneCB(
- kDefaultDuration(), expected_status));
+ demuxer_->Initialize(
+ &host_, CreateInitDoneCB(kDefaultDuration(), expected_status));
return AppendInfoTracks(has_audio, has_video, video_content_encoded);
}
@@ -270,7 +269,8 @@ class ChunkDemuxerTest : public testing::Test {
int buffer_size = 0;
EXPECT_CALL(*client_, DemuxerOpened(_));
- demuxer_->Initialize(CreateInitDoneCB(duration, PIPELINE_OK));
+ demuxer_->Initialize(
+ &host_, CreateInitDoneCB(duration, PIPELINE_OK));
// Read a WebM file into memory and send the data to the demuxer.
ReadTestDataFile(filename, &buffer, &buffer_size);
@@ -314,7 +314,7 @@ class ChunkDemuxerTest : public testing::Test {
return true;
}
- MockDemuxerHost mock_demuxer_host_;
+ MockDemuxerHost host_;
scoped_ptr<MockChunkDemuxerClient> client_;
scoped_refptr<ChunkDemuxer> demuxer_;
@@ -337,7 +337,6 @@ TEST_F(ChunkDemuxerTest, TestInit) {
client_.reset(new MockChunkDemuxerClient());
demuxer_ = new ChunkDemuxer(client_.get());
- demuxer_->set_host(&mock_demuxer_host_);
ASSERT_TRUE(InitDemuxer(has_audio, has_video, video_content_encoded));
scoped_refptr<DemuxerStream> audio_stream =
@@ -520,7 +519,7 @@ TEST_F(ChunkDemuxerTest, TestOutOfOrderClusters) {
// Make sure that AppendData() fails because this cluster data
// is before previous data.
- EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
+ EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size()));
// Verify that AppendData() doesn't accept more data now.
@@ -545,7 +544,7 @@ TEST_F(ChunkDemuxerTest, TestNonMonotonicButAboveClusterTimecode) {
AddSimpleBlock(&cb, kVideoTrackNum, 15);
scoped_ptr<Cluster> cluster_a(cb.Finish());
- EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
+ EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size()));
// Verify that AppendData() doesn't accept more data now.
@@ -570,7 +569,7 @@ TEST_F(ChunkDemuxerTest, TestBackwardsAndBeforeClusterTimecode) {
AddSimpleBlock(&cb, kVideoTrackNum, 3);
scoped_ptr<Cluster> cluster_a(cb.Finish());
- EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
+ EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size()));
// Verify that AppendData() doesn't accept more data now.
@@ -596,7 +595,7 @@ TEST_F(ChunkDemuxerTest, TestPerStreamMonotonicallyIncreasingTimestamps) {
AddSimpleBlock(&cb, kVideoTrackNum, 7);
scoped_ptr<Cluster> cluster(cb.Finish());
- EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
+ EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
ASSERT_TRUE(AppendData(cluster->data(), cluster->size()));
}
@@ -619,7 +618,7 @@ TEST_F(ChunkDemuxerTest, TestMonotonicallyIncreasingTimestampsAcrossClusters) {
AddSimpleBlock(&cb, kVideoTrackNum, 7);
scoped_ptr<Cluster> cluster_b(cb.Finish());
- EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
+ EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size()));
// Verify that AppendData() doesn't accept more data now.
@@ -634,7 +633,8 @@ TEST_F(ChunkDemuxerTest, TestMonotonicallyIncreasingTimestampsAcrossClusters) {
// INFO & TRACKS data.
TEST_F(ChunkDemuxerTest, TestClusterBeforeInfoTracks) {
EXPECT_CALL(*client_, DemuxerOpened(_));
- demuxer_->Initialize(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
+ demuxer_->Initialize(
+ &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
ClusterBuilder cb;
cb.SetClusterTimecode(0);
@@ -647,7 +647,8 @@ TEST_F(ChunkDemuxerTest, TestClusterBeforeInfoTracks) {
// Test cases where we get an EndOfStream() call during initialization.
TEST_F(ChunkDemuxerTest, TestEOSDuringInit) {
EXPECT_CALL(*client_, DemuxerOpened(_));
- demuxer_->Initialize(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
+ demuxer_->Initialize(
+ &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
demuxer_->EndOfStream(PIPELINE_OK);
}
@@ -663,7 +664,7 @@ TEST_F(ChunkDemuxerTest, TestDecodeErrorEndOfStream) {
scoped_ptr<Cluster> cluster(cb.Finish());
ASSERT_TRUE(AppendData(cluster->data(), cluster->size()));
- EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
+ EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
demuxer_->EndOfStream(PIPELINE_ERROR_DECODE);
}
@@ -679,7 +680,7 @@ TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) {
scoped_ptr<Cluster> cluster(cb.Finish());
ASSERT_TRUE(AppendData(cluster->data(), cluster->size()));
- EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_NETWORK));
+ EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_NETWORK));
demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK);
}
@@ -831,7 +832,8 @@ TEST_F(ChunkDemuxerTest, TestReadsAfterEndOfStream) {
TEST_F(ChunkDemuxerTest, TestAppendingInPieces) {
EXPECT_CALL(*client_, DemuxerOpened(_));
- demuxer_->Initialize(CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK));
+ demuxer_->Initialize(
+ &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK));
scoped_array<uint8> info_tracks;
int info_tracks_size = 0;
@@ -1026,11 +1028,11 @@ TEST_F(ChunkDemuxerTest, TestIncrementalClusterParsing) {
TEST_F(ChunkDemuxerTest, TestParseErrorDuringInit) {
- EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
+ EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
EXPECT_CALL(*client_, DemuxerOpened(_));
- demuxer_->Initialize(CreateInitDoneCB(
- kDefaultDuration(), PIPELINE_OK));
+ demuxer_->Initialize(
+ &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK));
ASSERT_TRUE(AppendInfoTracks(true, true, false));
uint8 tmp = 0;
View
9 media/filters/dummy_demuxer.cc
@@ -47,19 +47,16 @@ DummyDemuxer::DummyDemuxer(bool has_video, bool has_audio, bool local_source)
DummyDemuxer::~DummyDemuxer() {}
-void DummyDemuxer::Initialize(const PipelineStatusCB& status_cb) {
+void DummyDemuxer::Initialize(DemuxerHost* host,
+ const PipelineStatusCB& status_cb) {
+ host->SetDuration(media::kInfiniteDuration());
status_cb.Run(PIPELINE_OK);
}
scoped_refptr<DemuxerStream> DummyDemuxer::GetStream(DemuxerStream::Type type) {
return streams_[type];
}
-void DummyDemuxer::set_host(DemuxerHost* demuxer_host) {
- Demuxer::set_host(demuxer_host);
- host()->SetDuration(media::kInfiniteDuration());
-}
-
base::TimeDelta DummyDemuxer::GetStartTime() const {
return base::TimeDelta();
}
View
4 media/filters/dummy_demuxer.h
@@ -45,10 +45,10 @@ class MEDIA_EXPORT DummyDemuxer : public Demuxer {
virtual ~DummyDemuxer();
// Demuxer implementation.
- virtual void Initialize(const PipelineStatusCB& status_cb) OVERRIDE;
+ virtual void Initialize(DemuxerHost* host,
+ const PipelineStatusCB& status_cb) OVERRIDE;
virtual scoped_refptr<DemuxerStream> GetStream(
DemuxerStream::Type type) OVERRIDE;
- virtual void set_host(DemuxerHost* demuxer_host) OVERRIDE;
virtual base::TimeDelta GetStartTime() const OVERRIDE;
virtual int GetBitrate() OVERRIDE;
virtual bool IsLocalSource() OVERRIDE;
View
34 media/filters/ffmpeg_demuxer.cc
@@ -280,7 +280,8 @@ FFmpegDemuxer::FFmpegDemuxer(
MessageLoop* message_loop,
const scoped_refptr<DataSource>& data_source,
bool local_source)
- : message_loop_(message_loop),
+ : host_(NULL),
+ message_loop_(message_loop),
local_source_(local_source),
format_context_(NULL),
data_source_(data_source),
@@ -338,14 +339,10 @@ void FFmpegDemuxer::OnAudioRendererDisabled() {
&FFmpegDemuxer::DisableAudioStreamTask, this));
}
-void FFmpegDemuxer::set_host(DemuxerHost* demuxer_host) {
- Demuxer::set_host(demuxer_host);
- data_source_->set_host(demuxer_host);
-}
-
-void FFmpegDemuxer::Initialize(const PipelineStatusCB& status_cb) {
+void FFmpegDemuxer::Initialize(DemuxerHost* host,
+ const PipelineStatusCB& status_cb) {
message_loop_->PostTask(FROM_HERE, base::Bind(
- &FFmpegDemuxer::InitializeTask, this, status_cb));
+ &FFmpegDemuxer::InitializeTask, this, host, status_cb));
}
scoped_refptr<DemuxerStream> FFmpegDemuxer::GetStream(
@@ -364,6 +361,7 @@ base::TimeDelta FFmpegDemuxer::GetStartTime() const {
}
size_t FFmpegDemuxer::Read(size_t size, uint8* data) {
+ DCHECK(host_);
DCHECK(data_source_);
// If read has ever failed, return with an error.
@@ -386,24 +384,26 @@ size_t FFmpegDemuxer::Read(size_t size, uint8* data) {
// let FFmpeg demuxer methods to run on.
int last_read_bytes = WaitForRead();
if (last_read_bytes == DataSource::kReadError) {
- host()->OnDemuxerError(PIPELINE_ERROR_READ);
+ host_->OnDemuxerError(PIPELINE_ERROR_READ);
// Returns with a negative number to signal an error to FFmpeg.
read_has_failed_ = true;
return AVERROR(EIO);
}
read_position_ += last_read_bytes;
- host()->SetCurrentReadPosition(read_position_);
+ host_->SetCurrentReadPosition(read_position_);
return last_read_bytes;
}
bool FFmpegDemuxer::GetPosition(int64* position_out) {
+ DCHECK(host_);
*position_out = read_position_;
return true;
}
bool FFmpegDemuxer::SetPosition(int64 position) {
+ DCHECK(host_);
DCHECK(data_source_);
int64 file_size;
@@ -417,14 +417,14 @@ bool FFmpegDemuxer::SetPosition(int64 position) {
}
bool FFmpegDemuxer::GetSize(int64* size_out) {
+ DCHECK(host_);
DCHECK(data_source_);
-
return data_source_->GetSize(size_out);
}
bool FFmpegDemuxer::IsStreaming() {
+ DCHECK(host_);
DCHECK(data_source_);
-
return data_source_->IsStreaming();
}
@@ -468,8 +468,14 @@ static int CalculateBitrate(
return bytes * 8000000.0 / duration_us;
}
-void FFmpegDemuxer::InitializeTask(const PipelineStatusCB& status_cb) {
+void FFmpegDemuxer::InitializeTask(DemuxerHost* host,
+ const PipelineStatusCB& status_cb) {
DCHECK_EQ(MessageLoop::current(), message_loop_);
+ host_ = host;
+
+ // TODO(scherkus): DataSource should have a host by this point,
+ // see http://crbug.com/122071
+ data_source_->set_host(host);
// Add ourself to Protocol list and get our unique key.
std::string key = FFmpegGlue::GetInstance()->AddProtocol(this);
@@ -558,7 +564,7 @@ void FFmpegDemuxer::InitializeTask(const PipelineStatusCB& status_cb) {
// Good to go: set the duration and bitrate and notify we're done
// initializing.
- host()->SetDuration(max_duration);
+ host_->SetDuration(max_duration);
int64 filesize_in_bytes = 0;
GetSize(&filesize_in_bytes);
View
8 media/filters/ffmpeg_demuxer.h
@@ -139,8 +139,8 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer, public FFmpegURLProtocol {
virtual void PostDemuxTask();
// Demuxer implementation.
- virtual void set_host(DemuxerHost* demuxer_host) OVERRIDE;
- virtual void Initialize(const PipelineStatusCB& status_cb) OVERRIDE;
+ virtual void Initialize(DemuxerHost* host,
+ const PipelineStatusCB& status_cb) OVERRIDE;
virtual void Stop(const base::Closure& callback) OVERRIDE;
virtual void Seek(base::TimeDelta time, const PipelineStatusCB& cb) OVERRIDE;
virtual void OnAudioRendererDisabled() OVERRIDE;
@@ -171,7 +171,7 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer, public FFmpegURLProtocol {
FRIEND_TEST_ALL_PREFIXES(FFmpegDemuxerTest, ProtocolRead);
// Carries out initialization on the demuxer thread.
- void InitializeTask(const PipelineStatusCB& status_cb);
+ void InitializeTask(DemuxerHost* host, const PipelineStatusCB& status_cb);
// Carries out a seek on the demuxer thread.
void SeekTask(base::TimeDelta time, const PipelineStatusCB& cb);
@@ -204,6 +204,8 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer, public FFmpegURLProtocol {
// read or kReadError in case of error.
virtual void SignalReadCompleted(int size);
+ DemuxerHost* host_;
+
MessageLoop* message_loop_;
// True if the media is a local resource, false if the media require network
View
120 media/filters/ffmpeg_demuxer_unittest.cc
@@ -5,6 +5,7 @@
#include <deque>
#include "base/file_path.h"
+#include "base/file_util.h"
#include "base/path_service.h"
#include "base/threading/thread.h"
#include "media/base/filters.h"
@@ -72,16 +73,13 @@ class FFmpegDemuxerTest : public testing::Test {
// Create an FFmpegDemuxer with local data source.
demuxer_ = new FFmpegDemuxer(&message_loop_, data_source_, true);
demuxer_->disable_first_seek_hack_for_testing();
-
- // Inject a filter host and message loop and prepare a data source.
- demuxer_->set_host(&host_);
}
MOCK_METHOD1(CheckPoint, void(int v));
void InitializeDemuxer() {
EXPECT_CALL(host_, SetDuration(_));
- demuxer_->Initialize(NewExpectedStatusCB(PIPELINE_OK));
+ demuxer_->Initialize(&host_, NewExpectedStatusCB(PIPELINE_OK));
message_loop_.RunAllPending();
}
@@ -149,7 +147,8 @@ TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) {
// Simulate avformat_open_input() failing.
CreateDemuxer("ten_byte_file"),
EXPECT_CALL(host_, SetCurrentReadPosition(_));
- demuxer_->Initialize(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
+ demuxer_->Initialize(
+ &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
message_loop_.RunAllPending();
}
@@ -160,7 +159,7 @@ TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) {
//TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) {
// CreateDemuxer("find_stream_info_fail.webm");
// demuxer_->Initialize(
-// NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE));
+// &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE));
// message_loop_.RunAllPending();
//}
@@ -169,15 +168,15 @@ TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) {
CreateDemuxer("no_streams.webm");
EXPECT_CALL(host_, SetCurrentReadPosition(_));
demuxer_->Initialize(
- NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
+ &host_, NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
message_loop_.RunAllPending();
}
TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) {
// Open a file containing streams but none of which are audio/video streams.
CreateDemuxer("no_audio_video.webm");
demuxer_->Initialize(
- NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
+ &host_, NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
message_loop_.RunAllPending();
}
@@ -558,82 +557,49 @@ TEST_F(FFmpegDemuxerTest, DisableAudioStream) {
EXPECT_TRUE(reader->buffer()->IsEndOfStream());
}
-class MockFFmpegDemuxer : public FFmpegDemuxer {
- public:
- MockFFmpegDemuxer(MessageLoop* message_loop,
- const scoped_refptr<DataSource>& data_source)
- : FFmpegDemuxer(message_loop, data_source, true) {
- }
- virtual ~MockFFmpegDemuxer() {}
-
- MOCK_METHOD0(WaitForRead, int());
- MOCK_METHOD1(SignalReadCompleted, void(int size));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockFFmpegDemuxer);
-};
-
-// A gmock helper method to execute the callback and deletes it.
-void RunCallback(int size, const DataSource::ReadCB& callback) {
- DCHECK(!callback.is_null());
- callback.Run(size);
-}
-
TEST_F(FFmpegDemuxerTest, ProtocolRead) {
- scoped_refptr<StrictMock<MockDataSource> > data_source =
- new StrictMock<MockDataSource>();
+ CreateDemuxer("bear-320x240.webm");
+ InitializeDemuxer();
- EXPECT_CALL(*data_source, Stop(_))
- .WillRepeatedly(Invoke(&RunStopFilterCallback));
+ // Set read head to zero as Initialize() will have parsed a bit of the file.
+ int64 position = 0;
+ EXPECT_TRUE(demuxer_->SetPosition(0));
+ EXPECT_TRUE(demuxer_->GetPosition(&position));
+ EXPECT_EQ(0, position);
- // Creates a demuxer.
- scoped_refptr<MockFFmpegDemuxer> demuxer(
- new MockFFmpegDemuxer(&message_loop_, data_source));
- demuxer->set_host(&host_);
+ // Read 32 bytes from offset zero and verify position.
+ uint8 buffer[32];
+ EXPECT_EQ(32u, demuxer_->Read(32, buffer));
+ EXPECT_EQ(32, current_read_position_);
+ EXPECT_TRUE(demuxer_->GetPosition(&position));
+ EXPECT_EQ(32, position);
- uint8 kBuffer[1];
- InSequence s;
- // Actions taken in the first read.
- EXPECT_CALL(*data_source, GetSize(_))
- .WillOnce(DoAll(SetArgPointee<0>(1024), Return(true)));
- EXPECT_CALL(*data_source, Read(0, 512, kBuffer, _))
- .WillOnce(WithArgs<1, 3>(Invoke(&RunCallback)));
- EXPECT_CALL(*demuxer, SignalReadCompleted(512));
- EXPECT_CALL(*demuxer, WaitForRead())
- .WillOnce(Return(512));
- EXPECT_CALL(host_, SetCurrentReadPosition(512));
-
- // Second read.
- EXPECT_CALL(*data_source, GetSize(_))
- .WillOnce(DoAll(SetArgPointee<0>(1024), Return(true)));
- EXPECT_CALL(*data_source, Read(512, 512, kBuffer, _))
- .WillOnce(WithArgs<1, 3>(Invoke(&RunCallback)));
- EXPECT_CALL(*demuxer, SignalReadCompleted(512));
- EXPECT_CALL(*demuxer, WaitForRead())
- .WillOnce(Return(512));
- EXPECT_CALL(host_, SetCurrentReadPosition(1024));
-
- // Third read will fail because it exceeds the file size.
- EXPECT_CALL(*data_source, GetSize(_))
- .WillOnce(DoAll(SetArgPointee<0>(1024), Return(true)));
-
- // First read.
- EXPECT_EQ(512u, demuxer->Read(512, kBuffer));
- int64 position;
- EXPECT_TRUE(demuxer->GetPosition(&position));
- EXPECT_EQ(512, position);
+ // Read an additional 32 bytes and verify position.
+ EXPECT_EQ(32u, demuxer_->Read(32, buffer));
+ EXPECT_EQ(64, current_read_position_);
+ EXPECT_TRUE(demuxer_->GetPosition(&position));
+ EXPECT_EQ(64, position);
- // Second read.
- EXPECT_EQ(512u, demuxer->Read(512, kBuffer));
- EXPECT_TRUE(demuxer->GetPosition(&position));
- EXPECT_EQ(1024, position);
+ // Seek to end and read until EOF.
+ int64 size = 0;
+ EXPECT_TRUE(demuxer_->GetSize(&size));
+ EXPECT_TRUE(demuxer_->SetPosition(size - 48));
+ EXPECT_EQ(32u, demuxer_->Read(32, buffer));
+ EXPECT_EQ(size - 16, current_read_position_);
+ EXPECT_TRUE(demuxer_->GetPosition(&position));
+ EXPECT_EQ(size - 16, position);
+
+ EXPECT_EQ(16u, demuxer_->Read(32, buffer));
+ EXPECT_EQ(size, current_read_position_);
+ EXPECT_TRUE(demuxer_->GetPosition(&position));
+ EXPECT_EQ(size, position);
- // Third read will get an end-of-file error, which is represented as zero.
- EXPECT_EQ(0u, demuxer->Read(512, kBuffer));
+ EXPECT_EQ(0u, demuxer_->Read(32, buffer));
+ EXPECT_EQ(size, current_read_position_);
+ EXPECT_TRUE(demuxer_->GetPosition(&position));
+ EXPECT_EQ(size, position);
- // This read complete signal is generated when demuxer is stopped.
- EXPECT_CALL(*demuxer, SignalReadCompleted(DataSource::kReadError));
- demuxer->Stop(NewExpectedClosure());
+ demuxer_->Stop(NewExpectedClosure());
message_loop_.RunAllPending();
}
View
17 media/tools/seek_tester/seek_tester.cc
@@ -22,6 +22,20 @@
#include "media/filters/ffmpeg_demuxer.h"
#include "media/filters/file_data_source.h"
+class DemuxerHostImpl : public media::DemuxerHost {
+ public:
+ // DataSourceHost implementation.
+ virtual void SetTotalBytes(int64 total_bytes) OVERRIDE {}
+ virtual void SetBufferedBytes(int64 buffered_bytes) OVERRIDE {}
+ virtual void SetNetworkActivity(bool is_downloading_data) OVERRIDE {}
+
+ // DemuxerHost implementation.
+ virtual void SetDuration(base::TimeDelta duration) OVERRIDE {}
+ virtual void SetBufferedTime(base::TimeDelta buffered_time) OVERRIDE {}
+ virtual void SetCurrentReadPosition(int64 offset) OVERRIDE {}
+ virtual void OnDemuxerError(media::PipelineStatus error) OVERRIDE {}
+};
+
void QuitMessageLoop(MessageLoop* loop, media::PipelineStatus status) {
CHECK_EQ(status, media::PIPELINE_OK);
loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
@@ -48,11 +62,12 @@ int main(int argc, char** argv) {
new media::FileDataSource());
CHECK_EQ(file_data_source->Initialize(argv[1]), media::PIPELINE_OK);
+ DemuxerHostImpl host;
MessageLoop loop;
media::PipelineStatusCB quitter = base::Bind(&QuitMessageLoop, &loop);
scoped_refptr<media::FFmpegDemuxer> demuxer(
new media::FFmpegDemuxer(&loop, file_data_source, true));
- demuxer->Initialize(quitter);
+ demuxer->Initialize(&host, quitter);
loop.Run();
demuxer->Seek(base::TimeDelta::FromMilliseconds(seek_target_ms), quitter);

0 comments on commit d09ef25

Please sign in to comment.
Something went wrong with that request. Please try again.