Commit f5443ef7 authored by scherkus@chromium.org's avatar scherkus@chromium.org

Remove reference counting from media::Demuxer and friends.

In addition:
* Pipeline no longer owns the demuxer; clients are required to own it and keep it alive until Pipeline::Stop() completes.

BUG=173313

Review URL: https://codereview.chromium.org/13813016

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195437 0039d316-1c4b-4281-b951-d872f2087c98
parent 1f1057f9
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#ifndef MEDIA_BASE_DEMUXER_H_ #ifndef MEDIA_BASE_DEMUXER_H_
#define MEDIA_BASE_DEMUXER_H_ #define MEDIA_BASE_DEMUXER_H_
#include "base/memory/ref_counted.h"
#include "base/time.h" #include "base/time.h"
#include "media/base/data_source.h" #include "media/base/data_source.h"
#include "media/base/demuxer_stream.h" #include "media/base/demuxer_stream.h"
...@@ -28,9 +27,10 @@ class MEDIA_EXPORT DemuxerHost : public DataSourceHost { ...@@ -28,9 +27,10 @@ class MEDIA_EXPORT DemuxerHost : public DataSourceHost {
virtual ~DemuxerHost(); virtual ~DemuxerHost();
}; };
class MEDIA_EXPORT Demuxer : public base::RefCountedThreadSafe<Demuxer> { class MEDIA_EXPORT Demuxer {
public: public:
Demuxer(); Demuxer();
virtual ~Demuxer();
// Completes initialization of the demuxer. // Completes initialization of the demuxer.
// //
...@@ -64,10 +64,6 @@ class MEDIA_EXPORT Demuxer : public base::RefCountedThreadSafe<Demuxer> { ...@@ -64,10 +64,6 @@ class MEDIA_EXPORT Demuxer : public base::RefCountedThreadSafe<Demuxer> {
// Returns the starting time for the media file. // Returns the starting time for the media file.
virtual base::TimeDelta GetStartTime() const = 0; virtual base::TimeDelta GetStartTime() const = 0;
protected:
friend class base::RefCountedThreadSafe<Demuxer>;
virtual ~Demuxer();
private: private:
DISALLOW_COPY_AND_ASSIGN(Demuxer); DISALLOW_COPY_AND_ASSIGN(Demuxer);
}; };
......
...@@ -4,22 +4,21 @@ ...@@ -4,22 +4,21 @@
#include "media/base/filter_collection.h" #include "media/base/filter_collection.h"
#include "base/logging.h"
#include "media/base/audio_renderer.h" #include "media/base/audio_renderer.h"
#include "media/base/demuxer.h" #include "media/base/demuxer.h"
#include "media/base/video_renderer.h" #include "media/base/video_renderer.h"
namespace media { namespace media {
FilterCollection::FilterCollection() {} FilterCollection::FilterCollection() : demuxer_(NULL) {}
FilterCollection::~FilterCollection() {} FilterCollection::~FilterCollection() {}
void FilterCollection::SetDemuxer(const scoped_refptr<Demuxer>& demuxer) { void FilterCollection::SetDemuxer(Demuxer* demuxer) {
demuxer_ = demuxer; demuxer_ = demuxer;
} }
const scoped_refptr<Demuxer>& FilterCollection::GetDemuxer() { Demuxer* FilterCollection::GetDemuxer() {
return demuxer_; return demuxer_;
} }
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#ifndef MEDIA_BASE_FILTER_COLLECTION_H_ #ifndef MEDIA_BASE_FILTER_COLLECTION_H_
#define MEDIA_BASE_FILTER_COLLECTION_H_ #define MEDIA_BASE_FILTER_COLLECTION_H_
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "media/base/media_export.h" #include "media/base/media_export.h"
...@@ -25,8 +24,8 @@ class MEDIA_EXPORT FilterCollection { ...@@ -25,8 +24,8 @@ class MEDIA_EXPORT FilterCollection {
FilterCollection(); FilterCollection();
~FilterCollection(); ~FilterCollection();
void SetDemuxer(const scoped_refptr<Demuxer>& demuxer); void SetDemuxer(Demuxer* demuxer);
const scoped_refptr<Demuxer>& GetDemuxer(); Demuxer* GetDemuxer();
void SetAudioRenderer(scoped_ptr<AudioRenderer> audio_renderer); void SetAudioRenderer(scoped_ptr<AudioRenderer> audio_renderer);
scoped_ptr<AudioRenderer> GetAudioRenderer(); scoped_ptr<AudioRenderer> GetAudioRenderer();
...@@ -35,7 +34,7 @@ class MEDIA_EXPORT FilterCollection { ...@@ -35,7 +34,7 @@ class MEDIA_EXPORT FilterCollection {
scoped_ptr<VideoRenderer> GetVideoRenderer(); scoped_ptr<VideoRenderer> GetVideoRenderer();
private: private:
scoped_refptr<Demuxer> demuxer_; Demuxer* demuxer_;
scoped_ptr<AudioRenderer> audio_renderer_; scoped_ptr<AudioRenderer> audio_renderer_;
scoped_ptr<VideoRenderer> video_renderer_; scoped_ptr<VideoRenderer> video_renderer_;
......
...@@ -27,6 +27,7 @@ namespace media { ...@@ -27,6 +27,7 @@ namespace media {
class MockDemuxer : public Demuxer { class MockDemuxer : public Demuxer {
public: public:
MockDemuxer(); MockDemuxer();
virtual ~MockDemuxer();
// Demuxer implementation. // Demuxer implementation.
MOCK_METHOD2(Initialize, void(DemuxerHost* host, const PipelineStatusCB& cb)); MOCK_METHOD2(Initialize, void(DemuxerHost* host, const PipelineStatusCB& cb));
...@@ -37,9 +38,6 @@ class MockDemuxer : public Demuxer { ...@@ -37,9 +38,6 @@ class MockDemuxer : public Demuxer {
MOCK_METHOD1(GetStream, scoped_refptr<DemuxerStream>(DemuxerStream::Type)); MOCK_METHOD1(GetStream, scoped_refptr<DemuxerStream>(DemuxerStream::Type));
MOCK_CONST_METHOD0(GetStartTime, base::TimeDelta()); MOCK_CONST_METHOD0(GetStartTime, base::TimeDelta());
protected:
virtual ~MockDemuxer();
private: private:
DISALLOW_COPY_AND_ASSIGN(MockDemuxer); DISALLOW_COPY_AND_ASSIGN(MockDemuxer);
}; };
......
...@@ -81,6 +81,7 @@ Pipeline::Pipeline(const scoped_refptr<base::MessageLoopProxy>& message_loop, ...@@ -81,6 +81,7 @@ Pipeline::Pipeline(const scoped_refptr<base::MessageLoopProxy>& message_loop,
audio_ended_(false), audio_ended_(false),
video_ended_(false), video_ended_(false),
audio_disabled_(false), audio_disabled_(false),
demuxer_(NULL),
creation_time_(base::Time::Now()) { creation_time_(base::Time::Now()) {
media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated));
media_log_->AddEvent( media_log_->AddEvent(
...@@ -584,7 +585,7 @@ void Pipeline::DoSeek( ...@@ -584,7 +585,7 @@ void Pipeline::DoSeek(
// Seek demuxer. // Seek demuxer.
bound_fns.Push(base::Bind( bound_fns.Push(base::Bind(
&Demuxer::Seek, demuxer_, seek_timestamp)); &Demuxer::Seek, base::Unretained(demuxer_), seek_timestamp));
// Preroll renderers. // Preroll renderers.
if (audio_renderer_) { if (audio_renderer_) {
...@@ -628,8 +629,10 @@ void Pipeline::DoStop(const PipelineStatusCB& done_cb) { ...@@ -628,8 +629,10 @@ void Pipeline::DoStop(const PipelineStatusCB& done_cb) {
DCHECK(!pending_callbacks_.get()); DCHECK(!pending_callbacks_.get());
SerialRunner::Queue bound_fns; SerialRunner::Queue bound_fns;
if (demuxer_) if (demuxer_) {
bound_fns.Push(base::Bind(&Demuxer::Stop, demuxer_)); bound_fns.Push(base::Bind(
&Demuxer::Stop, base::Unretained(demuxer_)));
}
if (audio_renderer_) { if (audio_renderer_) {
bound_fns.Push(base::Bind( bound_fns.Push(base::Bind(
...@@ -913,13 +916,9 @@ void Pipeline::InitializeDemuxer(const PipelineStatusCB& done_cb) { ...@@ -913,13 +916,9 @@ void Pipeline::InitializeDemuxer(const PipelineStatusCB& done_cb) {
void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) { void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) {
DCHECK(message_loop_->BelongsToCurrentThread()); DCHECK(message_loop_->BelongsToCurrentThread());
scoped_refptr<DemuxerStream> stream =
demuxer_->GetStream(DemuxerStream::AUDIO);
DCHECK(stream);
audio_renderer_ = filter_collection_->GetAudioRenderer(); audio_renderer_ = filter_collection_->GetAudioRenderer();
audio_renderer_->Initialize( audio_renderer_->Initialize(
stream, demuxer_->GetStream(DemuxerStream::AUDIO),
done_cb, done_cb,
base::Bind(&Pipeline::OnUpdateStatistics, this), base::Bind(&Pipeline::OnUpdateStatistics, this),
base::Bind(&Pipeline::OnAudioUnderflow, this), base::Bind(&Pipeline::OnAudioUnderflow, this),
...@@ -934,7 +933,6 @@ void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) { ...@@ -934,7 +933,6 @@ void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) {
scoped_refptr<DemuxerStream> stream = scoped_refptr<DemuxerStream> stream =
demuxer_->GetStream(DemuxerStream::VIDEO); demuxer_->GetStream(DemuxerStream::VIDEO);
DCHECK(stream);
{ {
// Get an initial natural size so we have something when we signal // Get an initial natural size so we have something when we signal
......
...@@ -442,8 +442,6 @@ class MEDIA_EXPORT Pipeline ...@@ -442,8 +442,6 @@ class MEDIA_EXPORT Pipeline
// Set to true in DisableAudioRendererTask(). // Set to true in DisableAudioRendererTask().
bool audio_disabled_; bool audio_disabled_;
scoped_ptr<FilterCollection> filter_collection_;
// Temporary callback used for Start() and Seek(). // Temporary callback used for Start() and Seek().
PipelineStatusCB seek_cb_; PipelineStatusCB seek_cb_;
...@@ -456,14 +454,17 @@ class MEDIA_EXPORT Pipeline ...@@ -456,14 +454,17 @@ class MEDIA_EXPORT Pipeline
BufferingStateCB buffering_state_cb_; BufferingStateCB buffering_state_cb_;
base::Closure duration_change_cb_; base::Closure duration_change_cb_;
// Renderer references used for setting the volume, playback rate, and // Contains the demuxer and renderers to use when initializing.
// determining when playback has finished. scoped_ptr<FilterCollection> filter_collection_;
// Holds the initialized demuxer. Used for seeking. Owned by client.
Demuxer* demuxer_;
// Holds the initialized renderers. Used for setting the volume,
// playback rate, and determining when playback has finished.
scoped_ptr<AudioRenderer> audio_renderer_; scoped_ptr<AudioRenderer> audio_renderer_;
scoped_ptr<VideoRenderer> video_renderer_; scoped_ptr<VideoRenderer> video_renderer_;
// Demuxer reference used for setting the preload value.
scoped_refptr<Demuxer> demuxer_;
PipelineStatistics statistics_; PipelineStatistics statistics_;
// Time of pipeline creation; is non-zero only until the pipeline first // Time of pipeline creation; is non-zero only until the pipeline first
......
...@@ -83,9 +83,9 @@ class PipelineTest : public ::testing::Test { ...@@ -83,9 +83,9 @@ class PipelineTest : public ::testing::Test {
PipelineTest() PipelineTest()
: pipeline_(new Pipeline(message_loop_.message_loop_proxy(), : pipeline_(new Pipeline(message_loop_.message_loop_proxy(),
new MediaLog())), new MediaLog())),
filter_collection_(new FilterCollection()) { filter_collection_(new FilterCollection()),
demuxer_ = new MockDemuxer(); demuxer_(new MockDemuxer()) {
filter_collection_->SetDemuxer(demuxer_); filter_collection_->SetDemuxer(demuxer_.get());
video_renderer_ = new MockVideoRenderer(); video_renderer_ = new MockVideoRenderer();
scoped_ptr<VideoRenderer> video_renderer(video_renderer_); scoped_ptr<VideoRenderer> video_renderer(video_renderer_);
...@@ -295,7 +295,7 @@ class PipelineTest : public ::testing::Test { ...@@ -295,7 +295,7 @@ class PipelineTest : public ::testing::Test {
scoped_refptr<Pipeline> pipeline_; scoped_refptr<Pipeline> pipeline_;
scoped_ptr<FilterCollection> filter_collection_; scoped_ptr<FilterCollection> filter_collection_;
scoped_refptr<MockDemuxer> demuxer_; scoped_ptr<MockDemuxer> demuxer_;
MockVideoRenderer* video_renderer_; MockVideoRenderer* video_renderer_;
MockAudioRenderer* audio_renderer_; MockAudioRenderer* audio_renderer_;
scoped_refptr<StrictMock<MockDemuxerStream> > audio_stream_; scoped_refptr<StrictMock<MockDemuxerStream> > audio_stream_;
......
...@@ -45,6 +45,7 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer { ...@@ -45,6 +45,7 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer {
// console. // console.
ChunkDemuxer(const base::Closure& open_cb, const NeedKeyCB& need_key_cb, ChunkDemuxer(const base::Closure& open_cb, const NeedKeyCB& need_key_cb,
const LogCB& log_cb); const LogCB& log_cb);
virtual ~ChunkDemuxer();
// Demuxer implementation. // Demuxer implementation.
virtual void Initialize(DemuxerHost* host, virtual void Initialize(DemuxerHost* host,
...@@ -104,9 +105,6 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer { ...@@ -104,9 +105,6 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer {
bool EndOfStream(PipelineStatus status); bool EndOfStream(PipelineStatus status);
void Shutdown(); void Shutdown();
protected:
virtual ~ChunkDemuxer();
private: private:
enum State { enum State {
WAITING_FOR_INIT, WAITING_FOR_INIT,
......
...@@ -152,7 +152,7 @@ class ChunkDemuxerTest : public testing::Test { ...@@ -152,7 +152,7 @@ class ChunkDemuxerTest : public testing::Test {
base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this));
ChunkDemuxer::NeedKeyCB need_key_cb = ChunkDemuxer::NeedKeyCB need_key_cb =
base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this)); base::Bind(&ChunkDemuxerTest::DemuxerNeedKey, base::Unretained(this));
demuxer_ = new ChunkDemuxer(open_cb, need_key_cb, LogCB()); demuxer_.reset(new ChunkDemuxer(open_cb, need_key_cb, LogCB()));
} }
virtual ~ChunkDemuxerTest() { virtual ~ChunkDemuxerTest() {
...@@ -562,8 +562,7 @@ class ChunkDemuxerTest : public testing::Test { ...@@ -562,8 +562,7 @@ class ChunkDemuxerTest : public testing::Test {
} }
void Read(DemuxerStream::Type type, const DemuxerStream::ReadCB& read_cb) { void Read(DemuxerStream::Type type, const DemuxerStream::ReadCB& read_cb) {
scoped_refptr<DemuxerStream> stream = demuxer_->GetStream(type); demuxer_->GetStream(type)->Read(read_cb);
stream->Read(read_cb);
message_loop_.RunUntilIdle(); message_loop_.RunUntilIdle();
} }
...@@ -679,27 +678,24 @@ class ChunkDemuxerTest : public testing::Test { ...@@ -679,27 +678,24 @@ class ChunkDemuxerTest : public testing::Test {
} }
void ExpectEndOfStream(DemuxerStream::Type type) { void ExpectEndOfStream(DemuxerStream::Type type) {
scoped_refptr<DemuxerStream> stream = demuxer_->GetStream(type);
EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk, IsEndOfStream())); EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk, IsEndOfStream()));
stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone, demuxer_->GetStream(type)->Read(base::Bind(
base::Unretained(this))); &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
message_loop_.RunUntilIdle(); message_loop_.RunUntilIdle();
} }
void ExpectRead(DemuxerStream::Type type, int64 timestamp_in_ms) { void ExpectRead(DemuxerStream::Type type, int64 timestamp_in_ms) {
scoped_refptr<DemuxerStream> stream = demuxer_->GetStream(type);
EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk, EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk,
HasTimestamp(timestamp_in_ms))); HasTimestamp(timestamp_in_ms)));
stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone, demuxer_->GetStream(type)->Read(base::Bind(
base::Unretained(this))); &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
message_loop_.RunUntilIdle(); message_loop_.RunUntilIdle();
} }
void ExpectConfigChanged(DemuxerStream::Type type) { void ExpectConfigChanged(DemuxerStream::Type type) {
scoped_refptr<DemuxerStream> stream = demuxer_->GetStream(type);
EXPECT_CALL(*this, ReadDone(DemuxerStream::kConfigChanged, _)); EXPECT_CALL(*this, ReadDone(DemuxerStream::kConfigChanged, _));
stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone, demuxer_->GetStream(type)->Read(base::Bind(
base::Unretained(this))); &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
message_loop_.RunUntilIdle(); message_loop_.RunUntilIdle();
} }
...@@ -782,7 +778,7 @@ class ChunkDemuxerTest : public testing::Test { ...@@ -782,7 +778,7 @@ class ChunkDemuxerTest : public testing::Test {
MessageLoop message_loop_; MessageLoop message_loop_;
MockDemuxerHost host_; MockDemuxerHost host_;
scoped_refptr<ChunkDemuxer> demuxer_; scoped_ptr<ChunkDemuxer> demuxer_;
private: private:
DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest);
...@@ -846,7 +842,7 @@ TEST_F(ChunkDemuxerTest, TestInit) { ...@@ -846,7 +842,7 @@ TEST_F(ChunkDemuxerTest, TestInit) {
} }
ShutdownDemuxer(); ShutdownDemuxer();
demuxer_ = NULL; demuxer_.reset();
} }
} }
...@@ -1090,7 +1086,7 @@ TEST_F(ChunkDemuxerTest, TestEndOfStreamWithNoAppend) { ...@@ -1090,7 +1086,7 @@ TEST_F(ChunkDemuxerTest, TestEndOfStreamWithNoAppend) {
ShutdownDemuxer(); ShutdownDemuxer();
CheckExpectedRanges("{ }"); CheckExpectedRanges("{ }");
demuxer_->RemoveId(kSourceId); demuxer_->RemoveId(kSourceId);
demuxer_ = NULL; demuxer_.reset();
} }
TEST_F(ChunkDemuxerTest, TestEndOfStreamWithNoMediaAppend) { TEST_F(ChunkDemuxerTest, TestEndOfStreamWithNoMediaAppend) {
...@@ -1128,7 +1124,7 @@ TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) { ...@@ -1128,7 +1124,7 @@ TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) {
// Read() behavior. // Read() behavior.
class EndOfStreamHelper { class EndOfStreamHelper {
public: public:
explicit EndOfStreamHelper(const scoped_refptr<Demuxer> demuxer) explicit EndOfStreamHelper(Demuxer* demuxer)
: demuxer_(demuxer), : demuxer_(demuxer),
audio_read_done_(false), audio_read_done_(false),
video_read_done_(false) { video_read_done_(false) {
...@@ -1166,7 +1162,7 @@ class EndOfStreamHelper { ...@@ -1166,7 +1162,7 @@ class EndOfStreamHelper {
*called = true; *called = true;
} }
scoped_refptr<Demuxer> demuxer_; Demuxer* demuxer_;
bool audio_read_done_; bool audio_read_done_;
bool video_read_done_; bool video_read_done_;
...@@ -1183,8 +1179,8 @@ TEST_F(ChunkDemuxerTest, TestEndOfStreamWithPendingReads) { ...@@ -1183,8 +1179,8 @@ TEST_F(ChunkDemuxerTest, TestEndOfStreamWithPendingReads) {
bool audio_read_done_1 = false; bool audio_read_done_1 = false;
bool video_read_done_1 = false; bool video_read_done_1 = false;
EndOfStreamHelper end_of_stream_helper_1(demuxer_); EndOfStreamHelper end_of_stream_helper_1(demuxer_.get());
EndOfStreamHelper end_of_stream_helper_2(demuxer_); EndOfStreamHelper end_of_stream_helper_2(demuxer_.get());
ReadAudio(base::Bind(&OnReadDone, ReadAudio(base::Bind(&OnReadDone,
base::TimeDelta::FromMilliseconds(0), base::TimeDelta::FromMilliseconds(0),
...@@ -1219,9 +1215,9 @@ TEST_F(ChunkDemuxerTest, TestReadsAfterEndOfStream) { ...@@ -1219,9 +1215,9 @@ TEST_F(ChunkDemuxerTest, TestReadsAfterEndOfStream) {
bool audio_read_done_1 = false; bool audio_read_done_1 = false;
bool video_read_done_1 = false; bool video_read_done_1 = false;
EndOfStreamHelper end_of_stream_helper_1(demuxer_); EndOfStreamHelper end_of_stream_helper_1(demuxer_.get());
EndOfStreamHelper end_of_stream_helper_2(demuxer_); EndOfStreamHelper end_of_stream_helper_2(demuxer_.get());
EndOfStreamHelper end_of_stream_helper_3(demuxer_); EndOfStreamHelper end_of_stream_helper_3(demuxer_.get());
ReadAudio(base::Bind(&OnReadDone, ReadAudio(base::Bind(&OnReadDone,
base::TimeDelta::FromMilliseconds(0), base::TimeDelta::FromMilliseconds(0),
...@@ -2124,7 +2120,7 @@ TEST_F(ChunkDemuxerTest, TestEndOfStreamDuringSeek) { ...@@ -2124,7 +2120,7 @@ TEST_F(ChunkDemuxerTest, TestEndOfStreamDuringSeek) {
GenerateExpectedReads(0, 4); GenerateExpectedReads(0, 4);
GenerateExpectedReads(46, 66, 5); GenerateExpectedReads(46, 66, 5);
EndOfStreamHelper end_of_stream_helper(demuxer_); EndOfStreamHelper end_of_stream_helper(demuxer_.get());
end_of_stream_helper.RequestReads(); end_of_stream_helper.RequestReads();
end_of_stream_helper.CheckIfReadDonesWereCalled(true); end_of_stream_helper.CheckIfReadDonesWereCalled(true);
} }
...@@ -2185,7 +2181,7 @@ TEST_F(ChunkDemuxerTest, TestConfigChange_Audio) { ...@@ -2185,7 +2181,7 @@ TEST_F(ChunkDemuxerTest, TestConfigChange_Audio) {
DemuxerStream::Status status; DemuxerStream::Status status;
base::TimeDelta last_timestamp; base::TimeDelta last_timestamp;
scoped_refptr<DemuxerStream> audio = scoped_refptr<DemuxerStream> audio =
demuxer_->GetStream(DemuxerStream::AUDIO); demuxer_->GetStream(DemuxerStream::AUDIO);
// Fetch initial audio config and verify it matches what we expect. // Fetch initial audio config and verify it matches what we expect.
......
...@@ -43,7 +43,6 @@ FFmpegDemuxerStream::FFmpegDemuxerStream( ...@@ -43,7 +43,6 @@ FFmpegDemuxerStream::FFmpegDemuxerStream(
message_loop_(base::MessageLoopProxy::current()), message_loop_(base::MessageLoopProxy::current()),
stream_(stream), stream_(stream),
type_(UNKNOWN), type_(UNKNOWN),
stopped_(false),
end_of_stream_(false), end_of_stream_(false),
last_packet_timestamp_(kNoTimestamp()), last_packet_timestamp_(kNoTimestamp()),
bitstream_converter_enabled_(false) { bitstream_converter_enabled_(false) {
...@@ -98,7 +97,7 @@ FFmpegDemuxerStream::FFmpegDemuxerStream( ...@@ -98,7 +97,7 @@ FFmpegDemuxerStream::FFmpegDemuxerStream(
void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) { void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
DCHECK(message_loop_->BelongsToCurrentThread()); DCHECK(message_loop_->BelongsToCurrentThread());
if (stopped_ || end_of_stream_) { if (!demuxer_ || end_of_stream_) {
NOTREACHED() << "Attempted to enqueue packet on a stopped stream"; NOTREACHED() << "Attempted to enqueue packet on a stopped stream";
return; return;
} }
...@@ -178,7 +177,8 @@ void FFmpegDemuxerStream::Stop() { ...@@ -178,7 +177,8 @@ void FFmpegDemuxerStream::Stop() {
base::ResetAndReturn(&read_cb_).Run( base::ResetAndReturn(&read_cb_).Run(
DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer()); DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
} }
stopped_ = true; demuxer_ = NULL;
stream_ = NULL;
end_of_stream_ = true; end_of_stream_ = true;
} }
...@@ -200,7 +200,7 @@ void FFmpegDemuxerStream::Read(const ReadCB& read_cb) { ...@@ -200,7 +200,7 @@ void FFmpegDemuxerStream::Read(const ReadCB& read_cb) {
// The |demuxer_| may have been destroyed in the pipeline thread. // The |demuxer_| may have been destroyed in the pipeline thread.
// //
// TODO(scherkus): it would be cleaner to reply with an error message. // TODO(scherkus): it would be cleaner to reply with an error message.
if (stopped_) { if (!demuxer_) {
base::ResetAndReturn(&read_cb_).Run( base::ResetAndReturn(&read_cb_).Run(
DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer()); DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
return; return;
...@@ -228,7 +228,7 @@ const VideoDecoderConfig& FFmpegDemuxerStream::video_decoder_config() { ...@@ -228,7 +228,7 @@ const VideoDecoderConfig& FFmpegDemuxerStream::video_decoder_config() {
} }
FFmpegDemuxerStream::~FFmpegDemuxerStream() { FFmpegDemuxerStream::~FFmpegDemuxerStream() {
DCHECK(stopped_); DCHECK(!demuxer_);
DCHECK(read_cb_.is_null()); DCHECK(read_cb_.is_null());
DCHECK(buffer_queue_.IsEmpty()); DCHECK(buffer_queue_.IsEmpty());
} }
...@@ -288,6 +288,7 @@ FFmpegDemuxer::FFmpegDemuxer( ...@@ -288,6 +288,7 @@ FFmpegDemuxer::FFmpegDemuxer(
const FFmpegNeedKeyCB& need_key_cb) const FFmpegNeedKeyCB& need_key_cb)
: host_(NULL), : host_(NULL),
message_loop_(message_loop), message_loop_(message_loop),
weak_factory_(this),
blocking_thread_("FFmpegDemuxer"), blocking_thread_("FFmpegDemuxer"),
pending_read_(false), pending_read_(false),
pending_seek_(false), pending_seek_(false),
...@@ -309,7 +310,8 @@ void FFmpegDemuxer::Stop(const base::Closure& callback) { ...@@ -309,7 +310,8 @@ void FFmpegDemuxer::Stop(const base::Closure& callback) {
DCHECK(message_loop_->BelongsToCurrentThread()); DCHECK(message_loop_->BelongsToCurrentThread());
url_protocol_.Abort(); url_protocol_.Abort();
data_source_->Stop(BindToCurrentLoop(base::Bind( data_source_->Stop(BindToCurrentLoop(base::Bind(
&FFmpegDemuxer::OnDataSourceStopped, this, BindToCurrentLoop(callback)))); &FFmpegDemuxer::OnDataSourceStopped, weak_this_,
BindToCurrentLoop(callback))));
} }
void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) {
...@@ -331,7 +333,7 @@ void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { ...@@ -331,7 +333,7 @@ void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) {
blocking_thread_.message_loop_proxy(), FROM_HERE, blocking_thread_.message_loop_proxy(), FROM_HERE,
base::Bind(&av_seek_frame, glue_->format_context(), -1, base::Bind(&av_seek_frame, glue_->format_context(), -1,
time.InMicroseconds(), flags), time.InMicroseconds(), flags),
base::Bind(&FFmpegDemuxer::OnSeekFrameDone, this, cb)); base::Bind(&FFmpegDemuxer::OnSeekFrameDone, weak_this_, cb));
} }
void FFmpegDemuxer::SetPlaybackRate(float playback_rate) { void FFmpegDemuxer::SetPlaybackRate(float playback_rate) {
...@@ -354,6 +356,7 @@ void FFmpegDemuxer::Initialize(DemuxerHost* host, ...@@ -354,6 +356,7 @@ void FFmpegDemuxer::Initialize(DemuxerHost* host,
const PipelineStatusCB& status_cb) { const PipelineStatusCB& status_cb) {
DCHECK(message_loop_->BelongsToCurrentThread()); DCHECK(message_loop_->BelongsToCurrentThread());
host_ = host; host_ = host;
weak_this_ = weak_factory_.GetWeakPtr();
// TODO(scherkus): DataSource should have a host by this point, // TODO(scherkus): DataSource should have a host by this point,
// see http://crbug.com/122071 // see http://crbug.com/122071
...@@ -372,7 +375,7 @@ void FFmpegDemuxer::Initialize(DemuxerHost* host, ...@@ -372,7 +375,7 @@ void FFmpegDemuxer::Initialize(DemuxerHost* host,
base::PostTaskAndReplyWithResult( base::PostTaskAndReplyWithResult(
blocking_thread_.message_loop_proxy(), FROM_HERE, blocking_thread_.message_loop_proxy(), FROM_HERE,
base::Bind(&FFmpegGlue::OpenContext, base::Unretained(glue_.get())), base::Bind(&FFmpegGlue::OpenContext, base::Unretained(glue_.get())),
base::Bind(&FFmpegDemuxer::OnOpenContextDone, this, status_cb)); base::Bind(&FFmpegDemuxer::OnOpenContextDone, weak_this_, status_cb));
} }
scoped_refptr<DemuxerStream> FFmpegDemuxer::GetStream( scoped_refptr<DemuxerStream> FFmpegDemuxer::GetStream(
...@@ -451,7 +454,7 @@ void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB& status_cb, ...@@ -451,7 +454,7 @@ void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB& status_cb,
blocking_thread_.message_loop_proxy(), FROM_HERE, blocking_thread_.message_loop_proxy(), FROM_HERE,
base::Bind(&avformat_find_stream_info, glue_->format_context(), base::Bind(&avformat_find_stream_info, glue_->format_context(),
static_cast<AVDictionary**>(NULL)), static_cast<AVDictionary**>(NULL)),
base::Bind(&FFmpegDemuxer::OnFindStreamInfoDone, this, status_cb)); base::Bind(&FFmpegDemuxer::OnFindStreamInfoDone, weak_this_, status_cb));
} }
void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
...@@ -608,7 +611,8 @@ void FFmpegDemuxer::ReadFrameIfNeeded() { ...@@ -608,7 +611,8 @@ void FFmpegDemuxer::ReadFrameIfNeeded() {
base::PostTaskAndReplyWithResult( base::PostTaskAndReplyWithResult(
blocking_thread_.message_loop_proxy(), FROM_HERE, blocking_thread_.message_loop_proxy(), FROM_HERE,
base::Bind(&av_read_frame, glue_->format_context(), packet_ptr), base::Bind(&av_read_frame, glue_->format_context(), packet_ptr),
base::Bind(&FFmpegDemuxer::OnReadFrameDone, this, base::Passed(&packet))); base::Bind(&FFmpegDemuxer::OnReadFrameDone, weak_this_,
base::Passed(&packet)));
} }
void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) { void FFmpegDemuxer::OnReadFrameDone(ScopedAVPacket packet, int result) {
......
...@@ -119,7 +119,6 @@ class FFmpegDemuxerStream : public DemuxerStream { ...@@ -119,7 +119,6 @@ class FFmpegDemuxerStream : public DemuxerStream {
VideoDecoderConfig video_config_; VideoDecoderConfig video_config_;
Type type_; Type type_;
base::TimeDelta duration_; base::TimeDelta duration_;
bool stopped_;
bool end_of_stream_; bool end_of_stream_;
base::TimeDelta last_packet_timestamp_; base::TimeDelta last_packet_timestamp_;
Ranges<base::TimeDelta> buffered_ranges_; Ranges<base::TimeDelta> buffered_ranges_;
...@@ -140,6 +139,7 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer { ...@@ -140,6 +139,7 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer {
FFmpegDemuxer(const scoped_refptr<base::MessageLoopProxy>& message_loop, FFmpegDemuxer(const scoped_refptr<base::MessageLoopProxy>& message_loop,
const scoped_refptr<DataSource>& data_source, const scoped_refptr<DataSource>& data_source,
const FFmpegNeedKeyCB& need_key_cb); const FFmpegNeedKeyCB& need_key_cb);
virtual ~FFmpegDemuxer();
// Demuxer implementation. // Demuxer implementation.
virtual void Initialize(DemuxerHost* host, virtual void Initialize(DemuxerHost* host,
...@@ -165,8 +165,6 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer { ...@@ -165,8 +165,6 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer {
// To allow tests access to privates. // To allow tests access to privates.
friend class FFmpegDemuxerTest; friend class FFmpegDemuxerTest;
virtual ~FFmpegDemuxer();
// FFmpeg callbacks during initialization. // FFmpeg callbacks during initialization.
void OnOpenContextDone(const PipelineStatusCB& status_cb, bool result); void OnOpenContextDone(const PipelineStatusCB& status_cb, bool result);
void OnFindStreamInfoDone(const PipelineStatusCB& status_cb, int result); void OnFindStreamInfoDone(const PipelineStatusCB& status_cb, int result);
...@@ -199,6 +197,8 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer { ...@@ -199,6 +197,8 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer {
DemuxerHost* host_; DemuxerHost* host_;
scoped_refptr<base::MessageLoopProxy> message_loop_; scoped_refptr<base::MessageLoopProxy> message_loop_;
base::WeakPtrFactory<FFmpegDemuxer> weak_factory_;
base::WeakPtr<FFmpegDemuxer> weak_this_;
// Thread on which all blocking FFmpeg operations are executed. // Thread on which all blocking FFmpeg operations are executed.
base::Thread blocking_thread_; base::Thread blocking_thread_;
......
...@@ -69,8 +69,6 @@ class FFmpegDemuxerTest : public testing::Test { ...@@ -69,8 +69,6 @@ class FFmpegDemuxerTest : public testing::Test {
demuxer_->Stop(MessageLoop::QuitWhenIdleClosure()); demuxer_->Stop(MessageLoop::QuitWhenIdleClosure());
message_loop_.Run(); message_loop_.Run();
} }
demuxer_ = NULL;
} }
void CreateDemuxer(const std::string& name) { void CreateDemuxer(const std::string& name) {
...@@ -84,9 +82,8 @@ class FFmpegDemuxerTest : public testing::Test { ...@@ -84,9 +82,8 @@ class FFmpegDemuxerTest : public testing::Test {
media::FFmpegNeedKeyCB need_key_cb = media::FFmpegNeedKeyCB need_key_cb =
base::Bind(&FFmpegDemuxerTest::NeedKeyCB, base::Unretained(this)); base::Bind(&FFmpegDemuxerTest::NeedKeyCB, base::Unretained(this));
demuxer_ = new FFmpegDemuxer(message_loop_.message_loop_proxy(), demuxer_.reset(new FFmpegDemuxer(
data_source_, message_loop_.message_loop_proxy(), data_source_, need_key_cb));
need_key_cb);
} }
MOCK_METHOD1(CheckPoint, void(int v)); MOCK_METHOD1(CheckPoint, void(int v));
...@@ -148,12 +145,12 @@ class FFmpegDemuxerTest : public testing::Test { ...@@ -148,12 +145,12 @@ class FFmpegDemuxerTest : public testing::Test {
bool IsStreamStopped(DemuxerStream::Type type) { bool IsStreamStopped(DemuxerStream::Type type) {
DemuxerStream* stream = demuxer_->GetStream(type); DemuxerStream* stream = demuxer_->GetStream(type);
CHECK(stream); CHECK(stream);
return static_cast<FFmpegDemuxerStream*>(stream)->stopped_; return !static_cast<FFmpegDemuxerStream*>(stream)->demuxer_;
} }
// Fixture members. // Fixture members.
scoped_refptr<FileDataSource> data_source_; scoped_refptr<FileDataSource> data_source_;
scoped_refptr<FFmpegDemuxer> demuxer_; scoped_ptr<FFmpegDemuxer> demuxer_;
StrictMock<MockDemuxerHost> host_; StrictMock<MockDemuxerHost> host_;
MessageLoop message_loop_; MessageLoop message_loop_;
...@@ -508,9 +505,8 @@ TEST_F(FFmpegDemuxerTest, StreamReadAfterStopAndDemuxerDestruction) { ...@@ -508,9 +505,8 @@ TEST_F(FFmpegDemuxerTest, StreamReadAfterStopAndDemuxerDestruction) {
EXPECT_CALL(*callback, OnDelete()); EXPECT_CALL(*callback, OnDelete());
EXPECT_CALL(*this, CheckPoint(1)); EXPECT_CALL(*this, CheckPoint(1));
// Release the reference to the demuxer. This should also destroy it. // Destroy the demuxer. |audio| now has a demuxer_ pointer to invalid memory.
demuxer_ = NULL; demuxer_.reset();
// |audio| now has a demuxer_ pointer to invalid memory.
// Attempt the read... // Attempt the read...
audio->Read(base::Bind(&MockReadCB::Run, callback)); audio->Read(base::Bind(&MockReadCB::Run, callback));
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "media/base/decoder_buffer.h" #include "media/base/decoder_buffer.h"
#include "media/base/test_data_util.h" #include "media/base/test_data_util.h"
#include "media/crypto/aes_decryptor.h" #include "media/crypto/aes_decryptor.h"
#include "media/filters/chunk_demuxer.h"
using testing::AtMost; using testing::AtMost;
...@@ -230,11 +231,14 @@ class MockMediaSource { ...@@ -230,11 +231,14 @@ class MockMediaSource {
: file_path_(GetTestDataFilePath(filename)), : file_path_(GetTestDataFilePath(filename)),
current_position_(0), current_position_(0),
initial_append_size_(initial_append_size), initial_append_size_(initial_append_size),
mimetype_(mimetype) { mimetype_(mimetype),
chunk_demuxer_ = new ChunkDemuxer( chunk_demuxer_(new ChunkDemuxer(
base::Bind(&MockMediaSource::DemuxerOpened, base::Unretained(this)), base::Bind(&MockMediaSource::DemuxerOpened,
base::Bind(&MockMediaSource::DemuxerNeedKey, base::Unretained(this)), base::Unretained(this)),
LogCB()); base::Bind(&MockMediaSource::DemuxerNeedKey,
base::Unretained(this)),
LogCB())),
owned_chunk_demuxer_(chunk_demuxer_) {
file_data_ = ReadTestDataFile(filename); file_data_ = ReadTestDataFile(filename);
...@@ -247,7 +251,7 @@ class MockMediaSource { ...@@ -247,7 +251,7 @@ class MockMediaSource {
virtual ~MockMediaSource() {} virtual ~MockMediaSource() {}
const scoped_refptr<ChunkDemuxer>& demuxer() const { return chunk_demuxer_; } scoped_ptr<Demuxer> GetDemuxer() { return owned_chunk_demuxer_.Pass(); }
void set_need_key_cb(const NeedKeyCB& need_key_cb) { void set_need_key_cb(const NeedKeyCB& need_key_cb) {
need_key_cb_ = need_key_cb; need_key_cb_ = need_key_cb;
...@@ -266,7 +270,7 @@ class MockMediaSource { ...@@ -266,7 +270,7 @@ class MockMediaSource {
} }
void AppendData(int size) { void AppendData(int size) {
DCHECK(chunk_demuxer_.get()); DCHECK(chunk_demuxer_);
DCHECK_LT(current_position_, file_data_->GetDataSize()); DCHECK_LT(current_position_, file_data_->GetDataSize());
DCHECK_LE(current_position_ + size, file_data_->GetDataSize()); DCHECK_LE(current_position_ + size, file_data_->GetDataSize());
chunk_demuxer_->AppendData( chunk_demuxer_->AppendData(
...@@ -286,7 +290,7 @@ class MockMediaSource { ...@@ -286,7 +290,7 @@ class MockMediaSource {
} }
void Abort() { void Abort() {
if (!chunk_demuxer_.get()) if (!chunk_demuxer_)
return; return;
chunk_demuxer_->Shutdown(); chunk_demuxer_->Shutdown();
chunk_demuxer_ = NULL; chunk_demuxer_ = NULL;
...@@ -326,7 +330,8 @@ class MockMediaSource { ...@@ -326,7 +330,8 @@ class MockMediaSource {
int current_position_; int current_position_;
int initial_append_size_; int initial_append_size_;
std::string mimetype_; std::string mimetype_;
scoped_refptr<ChunkDemuxer> chunk_demuxer_; ChunkDemuxer* chunk_demuxer_;
scoped_ptr<Demuxer> owned_chunk_demuxer_;
NeedKeyCB need_key_cb_; NeedKeyCB need_key_cb_;
}; };
...@@ -340,7 +345,7 @@ class PipelineIntegrationTest ...@@ -340,7 +345,7 @@ class PipelineIntegrationTest
EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted)) EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted))
.Times(AtMost(1)); .Times(AtMost(1));
pipeline_->Start( pipeline_->Start(
CreateFilterCollection(source->demuxer(), NULL), CreateFilterCollection(source->GetDemuxer(), NULL),
base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)), base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)), base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
QuitOnStatusCB(PIPELINE_OK), QuitOnStatusCB(PIPELINE_OK),
...@@ -359,7 +364,8 @@ class PipelineIntegrationTest ...@@ -359,7 +364,8 @@ class PipelineIntegrationTest
EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted)) EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted))
.Times(AtMost(1)); .Times(AtMost(1));
pipeline_->Start( pipeline_->Start(
CreateFilterCollection(source->demuxer(), encrypted_media->decryptor()), CreateFilterCollection(source->GetDemuxer(),
encrypted_media->decryptor()),
base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)), base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)), base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
QuitOnStatusCB(PIPELINE_OK), QuitOnStatusCB(PIPELINE_OK),
......
...@@ -210,19 +210,19 @@ PipelineIntegrationTestBase::CreateFilterCollection( ...@@ -210,19 +210,19 @@ PipelineIntegrationTestBase::CreateFilterCollection(
media::FFmpegNeedKeyCB need_key_cb = media::FFmpegNeedKeyCB need_key_cb =
base::Bind(&PipelineIntegrationTestBase::DemuxerNeedKeyCB, base::Bind(&PipelineIntegrationTestBase::DemuxerNeedKeyCB,
base::Unretained(this)); base::Unretained(this));
return CreateFilterCollection( scoped_ptr<Demuxer> demuxer(new FFmpegDemuxer(
new FFmpegDemuxer(message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(), data_source, need_key_cb));
data_source, return CreateFilterCollection(demuxer.Pass(), decryptor);
need_key_cb),
decryptor);
} }
scoped_ptr<FilterCollection> scoped_ptr<FilterCollection>
PipelineIntegrationTestBase::CreateFilterCollection( PipelineIntegrationTestBase::CreateFilterCollection(
const scoped_refptr<Demuxer>& demuxer, scoped_ptr<Demuxer> demuxer,
Decryptor* decryptor) { Decryptor* decryptor) {
demuxer_ = demuxer.Pass();
scoped_ptr<FilterCollection> collection(new FilterCollection()); scoped_ptr<FilterCollection> collection(new FilterCollection());
collection->SetDemuxer(demuxer); collection->SetDemuxer(demuxer_.get());
ScopedVector<VideoDecoder> video_decoders; ScopedVector<VideoDecoder> video_decoders;
video_decoders.push_back( video_decoders.push_back(
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "media/audio/null_audio_sink.h" #include "media/audio/null_audio_sink.h"
#include "media/base/filter_collection.h" #include "media/base/filter_collection.h"
#include "media/base/pipeline.h" #include "media/base/pipeline.h"
#include "media/filters/chunk_demuxer.h"
#include "media/filters/video_renderer_base.h" #include "media/filters/video_renderer_base.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
...@@ -21,6 +20,7 @@ class FilePath; ...@@ -21,6 +20,7 @@ class FilePath;
namespace media { namespace media {
class Decryptor; class Decryptor;
class Demuxer;
// Empty MD5 hash string. Used to verify empty audio or video tracks. // Empty MD5 hash string. Used to verify empty audio or video tracks.
extern const char kNullHash[]; extern const char kNullHash[];
...@@ -74,6 +74,7 @@ class PipelineIntegrationTestBase { ...@@ -74,6 +74,7 @@ class PipelineIntegrationTestBase {
MessageLoop message_loop_; MessageLoop message_loop_;
base::MD5Context md5_context_; base::MD5Context md5_context_;
bool hashing_enabled_; bool hashing_enabled_;
scoped_ptr<Demuxer> demuxer_;
scoped_refptr<Pipeline> pipeline_; scoped_refptr<Pipeline> pipeline_;
scoped_refptr<NullAudioSink> audio_sink_; scoped_refptr<NullAudioSink> audio_sink_;
bool ended_; bool ended_;
...@@ -94,7 +95,7 @@ class PipelineIntegrationTestBase { ...@@ -94,7 +95,7 @@ class PipelineIntegrationTestBase {
void OnError(PipelineStatus status); void OnError(PipelineStatus status);
void QuitAfterCurrentTimeTask(const base::TimeDelta& quit_time); void QuitAfterCurrentTimeTask(const base::TimeDelta& quit_time);
scoped_ptr<FilterCollection> CreateFilterCollection( scoped_ptr<FilterCollection> CreateFilterCollection(
const scoped_refptr<Demuxer>& demuxer, Decryptor* decryptor); scoped_ptr<Demuxer> demuxer, Decryptor* decryptor);
void SetDecryptor(Decryptor* decryptor, void SetDecryptor(Decryptor* decryptor,
const DecryptorReadyCB& decryptor_ready_cb); const DecryptorReadyCB& decryptor_ready_cb);
void OnVideoRendererPaint(const scoped_refptr<VideoFrame>& frame); void OnVideoRendererPaint(const scoped_refptr<VideoFrame>& frame);
......
...@@ -54,7 +54,7 @@ typedef std::vector<scoped_refptr<media::DemuxerStream> > Streams; ...@@ -54,7 +54,7 @@ typedef std::vector<scoped_refptr<media::DemuxerStream> > Streams;
// present in |demuxer| in as-close-to-monotonically-increasing timestamp order. // present in |demuxer| in as-close-to-monotonically-increasing timestamp order.
class StreamReader { class StreamReader {
public: public:
explicit StreamReader(const scoped_refptr<media::Demuxer>& demuxer); explicit StreamReader(media::Demuxer* demuxer);
~StreamReader(); ~StreamReader();
// Performs a single step read. // Performs a single step read.
...@@ -83,7 +83,7 @@ class StreamReader { ...@@ -83,7 +83,7 @@ class StreamReader {
DISALLOW_COPY_AND_ASSIGN(StreamReader); DISALLOW_COPY_AND_ASSIGN(StreamReader);
}; };
StreamReader::StreamReader(const scoped_refptr<media::Demuxer> &demuxer) { StreamReader::StreamReader(media::Demuxer* demuxer) {
scoped_refptr<media::DemuxerStream> stream; scoped_refptr<media::DemuxerStream> stream;
stream = demuxer->GetStream(media::DemuxerStream::AUDIO); stream = demuxer->GetStream(media::DemuxerStream::AUDIO);
if (stream) { if (stream) {
...@@ -183,15 +183,14 @@ int main(int argc, char** argv) { ...@@ -183,15 +183,14 @@ int main(int argc, char** argv) {
CHECK(data_source->Initialize(file_path)); CHECK(data_source->Initialize(file_path));
media::FFmpegNeedKeyCB need_key_cb = base::Bind(&NeedKey); media::FFmpegNeedKeyCB need_key_cb = base::Bind(&NeedKey);
scoped_refptr<media::FFmpegDemuxer> demuxer = scoped_ptr<media::FFmpegDemuxer> demuxer(new media::FFmpegDemuxer(
new media::FFmpegDemuxer(message_loop.message_loop_proxy(), data_source, message_loop.message_loop_proxy(), data_source, need_key_cb));
need_key_cb);
demuxer->Initialize(&demuxer_host, base::Bind( demuxer->Initialize(&demuxer_host, base::Bind(
&QuitLoopWithStatus, &message_loop)); &QuitLoopWithStatus, &message_loop));
message_loop.Run(); message_loop.Run();
StreamReader stream_reader(demuxer); StreamReader stream_reader(demuxer.get());
// Benchmark. // Benchmark.
base::TimeTicks start = base::TimeTicks::HighResNow(); base::TimeTicks start = base::TimeTicks::HighResNow();
......
...@@ -102,7 +102,7 @@ static void NeedKey(const std::string& type, scoped_ptr<uint8[]> init_data, ...@@ -102,7 +102,7 @@ static void NeedKey(const std::string& type, scoped_ptr<uint8[]> init_data,
// TODO(vrk): Re-enabled audio. (crbug.com/112159) // TODO(vrk): Re-enabled audio. (crbug.com/112159)
bool InitPipeline(const scoped_refptr<base::MessageLoopProxy>& message_loop, bool InitPipeline(const scoped_refptr<base::MessageLoopProxy>& message_loop,
const scoped_refptr<media::DataSource>& data_source, media::Demuxer* demuxer,
const PaintCB& paint_cb, const PaintCB& paint_cb,
bool /* enable_audio */, bool /* enable_audio */,
scoped_refptr<media::Pipeline>* pipeline, scoped_refptr<media::Pipeline>* pipeline,
...@@ -110,10 +110,7 @@ bool InitPipeline(const scoped_refptr<base::MessageLoopProxy>& message_loop, ...@@ -110,10 +110,7 @@ bool InitPipeline(const scoped_refptr<base::MessageLoopProxy>& message_loop,
// Create our filter factories. // Create our filter factories.
scoped_ptr<media::FilterCollection> collection( scoped_ptr<media::FilterCollection> collection(
new media::FilterCollection()); new media::FilterCollection());
media::FFmpegNeedKeyCB need_key_cb = base::Bind(&NeedKey); collection->SetDemuxer(demuxer);
collection->SetDemuxer(new media::FFmpegDemuxer(message_loop, data_source,
need_key_cb));
ScopedVector<media::VideoDecoder> video_decoders; ScopedVector<media::VideoDecoder> video_decoders;
video_decoders.push_back(new media::FFmpegVideoDecoder(message_loop)); video_decoders.push_back(new media::FFmpegVideoDecoder(message_loop));
...@@ -281,8 +278,10 @@ int main(int argc, char** argv) { ...@@ -281,8 +278,10 @@ int main(int argc, char** argv) {
scoped_refptr<media::DataSource> data_source( scoped_refptr<media::DataSource> data_source(
new DataSourceLogger(CreateFileDataSource(filename), new DataSourceLogger(CreateFileDataSource(filename),
command_line->HasSwitch("streaming"))); command_line->HasSwitch("streaming")));
scoped_ptr<media::Demuxer> demuxer(new media::FFmpegDemuxer(
media_thread.message_loop_proxy(), data_source, base::Bind(&NeedKey)));
if (InitPipeline(media_thread.message_loop_proxy(), data_source, if (InitPipeline(media_thread.message_loop_proxy(), demuxer.get(),
paint_cb, command_line->HasSwitch("audio"), paint_cb, command_line->HasSwitch("audio"),
&pipeline, &message_loop)) { &pipeline, &message_loop)) {
// Main loop of the application. // Main loop of the application.
......
...@@ -73,9 +73,8 @@ int main(int argc, char** argv) { ...@@ -73,9 +73,8 @@ int main(int argc, char** argv) {
MessageLoop loop; MessageLoop loop;
media::PipelineStatusCB quitter = base::Bind(&QuitMessageLoop, &loop); media::PipelineStatusCB quitter = base::Bind(&QuitMessageLoop, &loop);
media::FFmpegNeedKeyCB need_key_cb = base::Bind(&NeedKey); media::FFmpegNeedKeyCB need_key_cb = base::Bind(&NeedKey);
scoped_refptr<media::FFmpegDemuxer> demuxer( scoped_ptr<media::FFmpegDemuxer> demuxer(new media::FFmpegDemuxer(
new media::FFmpegDemuxer(loop.message_loop_proxy(), file_data_source, loop.message_loop_proxy(), file_data_source, need_key_cb));
need_key_cb));
demuxer->Initialize(&host, quitter); demuxer->Initialize(&host, quitter);
loop.Run(); loop.Run();
......
...@@ -153,6 +153,7 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( ...@@ -153,6 +153,7 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(
is_local_source_(false), is_local_source_(false),
supports_save_(true), supports_save_(true),
starting_(false), starting_(false),
chunk_demuxer_(NULL),
pending_repaint_(false), pending_repaint_(false),
video_frame_provider_client_(NULL) { video_frame_provider_client_(NULL) {
media_log_->AddEvent( media_log_->AddEvent(
...@@ -266,18 +267,11 @@ void WebMediaPlayerImpl::load(const WebKit::WebURL& url, CORSMode cors_mode) { ...@@ -266,18 +267,11 @@ void WebMediaPlayerImpl::load(const WebKit::WebURL& url, CORSMode cors_mode) {
void WebMediaPlayerImpl::load(const WebKit::WebURL& url, void WebMediaPlayerImpl::load(const WebKit::WebURL& url,
WebKit::WebMediaSource* media_source, WebKit::WebMediaSource* media_source,
CORSMode cors_mode) { CORSMode cors_mode) {
scoped_ptr<WebKit::WebMediaSource> ms(media_source);
LoadSetup(url); LoadSetup(url);
// Media source pipelines can start immediately. // Media source pipelines can start immediately.
chunk_demuxer_ = new media::ChunkDemuxer(
BIND_TO_RENDER_LOOP_1(&WebMediaPlayerImpl::OnDemuxerOpened,
base::Passed(&ms)),
BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""),
base::Bind(&LogMediaSourceError, media_log_));
supports_save_ = false; supports_save_ = false;
StartPipeline(); StartPipeline(media_source);
} }
void WebMediaPlayerImpl::LoadSetup(const WebKit::WebURL& url) { void WebMediaPlayerImpl::LoadSetup(const WebKit::WebURL& url) {
...@@ -1122,7 +1116,7 @@ void WebMediaPlayerImpl::DataSourceInitialized(const GURL& gurl, bool success) { ...@@ -1122,7 +1116,7 @@ void WebMediaPlayerImpl::DataSourceInitialized(const GURL& gurl, bool success) {
return; return;
} }
StartPipeline(); StartPipeline(NULL);
} }
void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) {
...@@ -1136,10 +1130,97 @@ void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { ...@@ -1136,10 +1130,97 @@ void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) {
"is_downloading_data", is_downloading)); "is_downloading_data", is_downloading));
} }
void WebMediaPlayerImpl::StartPipeline() { void WebMediaPlayerImpl::StartPipeline(WebKit::WebMediaSource* media_source) {
const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
// Figure out which demuxer to use.
if (!media_source) {
DCHECK(!chunk_demuxer_);
DCHECK(data_source_);
demuxer_.reset(new media::FFmpegDemuxer(
media_thread_.message_loop_proxy(), data_source_,
BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", "")));
} else {
DCHECK(!chunk_demuxer_);
DCHECK(!data_source_);
scoped_ptr<WebKit::WebMediaSource> ms(media_source);
chunk_demuxer_ = new media::ChunkDemuxer(
BIND_TO_RENDER_LOOP_1(&WebMediaPlayerImpl::OnDemuxerOpened,
base::Passed(&ms)),
BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", ""),
base::Bind(&LogMediaSourceError, media_log_));
demuxer_.reset(chunk_demuxer_);
// Disable GpuVideoDecoder creation until it supports codec config changes.
// TODO(acolwell): Remove this once http://crbug.com/151045 is fixed.
gpu_factories_ = NULL;
}
scoped_ptr<media::FilterCollection> filter_collection(
new media::FilterCollection());
filter_collection->SetDemuxer(demuxer_.get());
// Figure out if EME is enabled.
media::SetDecryptorReadyCB set_decryptor_ready_cb;
if (decryptor_) {
set_decryptor_ready_cb = base::Bind(&ProxyDecryptor::SetDecryptorReadyCB,
base::Unretained(decryptor_.get()));
}
// Create our audio decoders and renderer.
ScopedVector<media::AudioDecoder> audio_decoders;
audio_decoders.push_back(new media::FFmpegAudioDecoder(
media_thread_.message_loop_proxy()));
if (cmd_line->HasSwitch(switches::kEnableOpusPlayback)) {
audio_decoders.push_back(new media::OpusAudioDecoder(
media_thread_.message_loop_proxy()));
}
scoped_ptr<media::AudioRenderer> audio_renderer(
new media::AudioRendererImpl(media_thread_.message_loop_proxy(),
audio_source_provider_,
audio_decoders.Pass(),
set_decryptor_ready_cb));
filter_collection->SetAudioRenderer(audio_renderer.Pass());
// Create our video decoders and renderer.
ScopedVector<media::VideoDecoder> video_decoders;
if (gpu_factories_) {
video_decoders.push_back(new media::GpuVideoDecoder(
media_thread_.message_loop_proxy(), gpu_factories_));
}
// TODO(phajdan.jr): Remove ifdefs when libvpx with vp9 support is released
// (http://crbug.com/174287) .
#if !defined(MEDIA_DISABLE_LIBVPX)
if (cmd_line->HasSwitch(switches::kEnableVp9Playback) ||
cmd_line->HasSwitch(switches::kEnableVp8AlphaPlayback)) {
video_decoders.push_back(new media::VpxVideoDecoder(
media_thread_.message_loop_proxy()));
}
#endif // !defined(MEDIA_DISABLE_LIBVPX)
video_decoders.push_back(new media::FFmpegVideoDecoder(
media_thread_.message_loop_proxy()));
scoped_ptr<media::VideoRenderer> video_renderer(
new media::VideoRendererBase(
media_thread_.message_loop_proxy(),
video_decoders.Pass(),
set_decryptor_ready_cb,
base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::SetOpaque),
true));
filter_collection->SetVideoRenderer(video_renderer.Pass());
// ... and we're ready to go!
starting_ = true; starting_ = true;
pipeline_->Start( pipeline_->Start(
BuildFilterCollection(), filter_collection.Pass(),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineSeek), BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineSeek),
...@@ -1175,8 +1256,10 @@ void WebMediaPlayerImpl::Destroy() { ...@@ -1175,8 +1256,10 @@ void WebMediaPlayerImpl::Destroy() {
// Abort any pending IO so stopping the pipeline doesn't get blocked. // Abort any pending IO so stopping the pipeline doesn't get blocked.
if (data_source_) if (data_source_)
data_source_->Abort(); data_source_->Abort();
if (chunk_demuxer_) if (chunk_demuxer_) {
chunk_demuxer_->Shutdown(); chunk_demuxer_->Shutdown();
chunk_demuxer_ = NULL;
}
if (gpu_factories_) { if (gpu_factories_) {
gpu_factories_->Abort(); gpu_factories_->Abort();
...@@ -1200,7 +1283,7 @@ void WebMediaPlayerImpl::Destroy() { ...@@ -1200,7 +1283,7 @@ void WebMediaPlayerImpl::Destroy() {
// Release any final references now that everything has stopped. // Release any final references now that everything has stopped.
data_source_ = NULL; data_source_ = NULL;
chunk_demuxer_ = NULL; demuxer_.reset();
} }
WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() {
...@@ -1250,83 +1333,4 @@ void WebMediaPlayerImpl::FrameReady( ...@@ -1250,83 +1333,4 @@ void WebMediaPlayerImpl::FrameReady(
&WebMediaPlayerImpl::Repaint, AsWeakPtr())); &WebMediaPlayerImpl::Repaint, AsWeakPtr()));
} }
scoped_ptr<media::FilterCollection>
WebMediaPlayerImpl::BuildFilterCollection() {
const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
scoped_ptr<media::FilterCollection> filter_collection(
new media::FilterCollection());
// Figure out which demuxer to use.
if (data_source_) {
DCHECK(!chunk_demuxer_);
filter_collection->SetDemuxer(new media::FFmpegDemuxer(
media_thread_.message_loop_proxy(), data_source_,
BIND_TO_RENDER_LOOP_2(&WebMediaPlayerImpl::OnNeedKey, "", "")));
} else {
DCHECK(chunk_demuxer_);
filter_collection->SetDemuxer(chunk_demuxer_);
// Disable GpuVideoDecoder creation until it supports codec config changes.
// TODO(acolwell): Remove this once http://crbug.com/151045 is fixed.
gpu_factories_ = NULL;
}
// Figure out if EME is enabled.
media::SetDecryptorReadyCB set_decryptor_ready_cb;
if (decryptor_) {
set_decryptor_ready_cb = base::Bind(&ProxyDecryptor::SetDecryptorReadyCB,
base::Unretained(decryptor_.get()));
}
// Create our audio decoders and renderer.
ScopedVector<media::AudioDecoder> audio_decoders;
audio_decoders.push_back(new media::FFmpegAudioDecoder(
media_thread_.message_loop_proxy()));
if (cmd_line->HasSwitch(switches::kEnableOpusPlayback)) {
audio_decoders.push_back(new media::OpusAudioDecoder(
media_thread_.message_loop_proxy()));
}
scoped_ptr<media::AudioRenderer> audio_renderer(
new media::AudioRendererImpl(media_thread_.message_loop_proxy(),
audio_source_provider_,
audio_decoders.Pass(),
set_decryptor_ready_cb));
filter_collection->SetAudioRenderer(audio_renderer.Pass());
// Create our video decoders and renderer.
ScopedVector<media::VideoDecoder> video_decoders;
if (gpu_factories_) {
video_decoders.push_back(new media::GpuVideoDecoder(
media_thread_.message_loop_proxy(), gpu_factories_));
}
// TODO(phajdan.jr): Remove ifdefs when libvpx with vp9 support is released
// (http://crbug.com/174287) .
#if !defined(MEDIA_DISABLE_LIBVPX)
if (cmd_line->HasSwitch(switches::kEnableVp9Playback) ||
cmd_line->HasSwitch(switches::kEnableVp8AlphaPlayback)) {
video_decoders.push_back(new media::VpxVideoDecoder(
media_thread_.message_loop_proxy()));
}
#endif // !defined(MEDIA_DISABLE_LIBVPX)
video_decoders.push_back(new media::FFmpegVideoDecoder(
media_thread_.message_loop_proxy()));
scoped_ptr<media::VideoRenderer> video_renderer(
new media::VideoRendererBase(
media_thread_.message_loop_proxy(),
video_decoders.Pass(),
set_decryptor_ready_cb,
base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::SetOpaque),
true));
filter_collection->SetVideoRenderer(video_renderer.Pass());
return filter_collection.Pass();
}
} // namespace webkit_media } // namespace webkit_media
...@@ -53,6 +53,7 @@ class MessageLoopProxy; ...@@ -53,6 +53,7 @@ class MessageLoopProxy;
namespace media { namespace media {
class ChunkDemuxer; class ChunkDemuxer;
class FFmpegDemuxer;
class MediaLog; class MediaLog;
} }
...@@ -230,7 +231,9 @@ class WebMediaPlayerImpl ...@@ -230,7 +231,9 @@ class WebMediaPlayerImpl
void NotifyDownloading(bool is_downloading); void NotifyDownloading(bool is_downloading);
// Finishes starting the pipeline due to a call to load(). // Finishes starting the pipeline due to a call to load().
void StartPipeline(); //
// A non-null |media_source| will construct a Media Source pipeline.
void StartPipeline(WebKit::WebMediaSource* media_source);
// Helpers that set the network/ready state and notifies the client if // Helpers that set the network/ready state and notifies the client if
// they've changed. // they've changed.
...@@ -272,10 +275,6 @@ class WebMediaPlayerImpl ...@@ -272,10 +275,6 @@ class WebMediaPlayerImpl
// painted. // painted.
void FrameReady(const scoped_refptr<media::VideoFrame>& frame); void FrameReady(const scoped_refptr<media::VideoFrame>& frame);
// Builds a FilterCollection based on the current configuration of
// WebMediaPlayerImpl.
scoped_ptr<media::FilterCollection> BuildFilterCollection();
WebKit::WebFrame* frame_; WebKit::WebFrame* frame_;
// TODO(hclam): get rid of these members and read from the pipeline directly. // TODO(hclam): get rid of these members and read from the pipeline directly.
...@@ -349,8 +348,12 @@ class WebMediaPlayerImpl ...@@ -349,8 +348,12 @@ class WebMediaPlayerImpl
// These two are mutually exclusive: // These two are mutually exclusive:
// |data_source_| is used for regular resource loads. // |data_source_| is used for regular resource loads.
// |chunk_demuxer_| is used for Media Source resource loads. // |chunk_demuxer_| is used for Media Source resource loads.
//
// |demuxer_| will contain the appropriate demuxer based on which resource
// load strategy we're using.
scoped_refptr<BufferedDataSource> data_source_; scoped_refptr<BufferedDataSource> data_source_;
scoped_refptr<media::ChunkDemuxer> chunk_demuxer_; scoped_ptr<media::Demuxer> demuxer_;
media::ChunkDemuxer* chunk_demuxer_;
// Temporary for EME v0.1. In the future the init data type should be passed // Temporary for EME v0.1. In the future the init data type should be passed
// through GenerateKeyRequest() directly from WebKit. // through GenerateKeyRequest() directly from WebKit.
......
...@@ -25,8 +25,7 @@ COMPILE_ASSERT_MATCHING_STATUS_ENUM(AddStatusReachedIdLimit, kReachedIdLimit); ...@@ -25,8 +25,7 @@ COMPILE_ASSERT_MATCHING_STATUS_ENUM(AddStatusReachedIdLimit, kReachedIdLimit);
#undef COMPILE_ASSERT_MATCHING_STATUS_ENUM #undef COMPILE_ASSERT_MATCHING_STATUS_ENUM
WebMediaSourceClientImpl::WebMediaSourceClientImpl( WebMediaSourceClientImpl::WebMediaSourceClientImpl(
const scoped_refptr<media::ChunkDemuxer>& demuxer, media::ChunkDemuxer* demuxer, media::LogCB log_cb)
media::LogCB log_cb)
: demuxer_(demuxer), : demuxer_(demuxer),
log_cb_(log_cb) { log_cb_(log_cb) {
DCHECK(demuxer_); DCHECK(demuxer_);
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/memory/ref_counted.h"
#include "media/base/media_log.h" #include "media/base/media_log.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaSourceClient.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaSourceClient.h"
...@@ -20,9 +19,7 @@ namespace webkit_media { ...@@ -20,9 +19,7 @@ namespace webkit_media {
class WebMediaSourceClientImpl : public WebKit::WebMediaSourceClient { class WebMediaSourceClientImpl : public WebKit::WebMediaSourceClient {
public: public:
explicit WebMediaSourceClientImpl( WebMediaSourceClientImpl(media::ChunkDemuxer* demuxer, media::LogCB log_cb);
const scoped_refptr<media::ChunkDemuxer>& demuxer,
media::LogCB log_cb);
virtual ~WebMediaSourceClientImpl(); virtual ~WebMediaSourceClientImpl();
// WebKit::WebMediaSourceClient implementation. // WebKit::WebMediaSourceClient implementation.
...@@ -35,7 +32,7 @@ class WebMediaSourceClientImpl : public WebKit::WebMediaSourceClient { ...@@ -35,7 +32,7 @@ class WebMediaSourceClientImpl : public WebKit::WebMediaSourceClient {
virtual void endOfStream(EndOfStreamStatus status) OVERRIDE; virtual void endOfStream(EndOfStreamStatus status) OVERRIDE;
private: private:
scoped_refptr<media::ChunkDemuxer> demuxer_; media::ChunkDemuxer* demuxer_; // Owned by WebMediaPlayerImpl.
media::LogCB log_cb_; media::LogCB log_cb_;
DISALLOW_COPY_AND_ASSIGN(WebMediaSourceClientImpl); DISALLOW_COPY_AND_ASSIGN(WebMediaSourceClientImpl);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
namespace webkit_media { namespace webkit_media {
WebSourceBufferImpl::WebSourceBufferImpl( WebSourceBufferImpl::WebSourceBufferImpl(
const std::string& id, scoped_refptr<media::ChunkDemuxer> demuxer) const std::string& id, media::ChunkDemuxer* demuxer)
: id_(id), : id_(id),
demuxer_(demuxer) { demuxer_(demuxer) {
DCHECK(demuxer_); DCHECK(demuxer_);
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
#include <string> #include <string>
#include "base/memory/ref_counted.h" #include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSourceBuffer.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebSourceBuffer.h"
namespace media { namespace media {
...@@ -18,8 +19,7 @@ namespace webkit_media { ...@@ -18,8 +19,7 @@ namespace webkit_media {
class WebSourceBufferImpl : public WebKit::WebSourceBuffer { class WebSourceBufferImpl : public WebKit::WebSourceBuffer {
public: public:
WebSourceBufferImpl(const std::string& id, WebSourceBufferImpl(const std::string& id, media::ChunkDemuxer* demuxer);
scoped_refptr<media::ChunkDemuxer> demuxer);
virtual ~WebSourceBufferImpl(); virtual ~WebSourceBufferImpl();
// WebKit::WebSourceBuffer implementation. // WebKit::WebSourceBuffer implementation.
...@@ -31,7 +31,7 @@ class WebSourceBufferImpl : public WebKit::WebSourceBuffer { ...@@ -31,7 +31,7 @@ class WebSourceBufferImpl : public WebKit::WebSourceBuffer {
private: private:
std::string id_; std::string id_;
scoped_refptr<media::ChunkDemuxer> demuxer_; media::ChunkDemuxer* demuxer_; // Owned by WebMediaPlayerImpl.
DISALLOW_COPY_AND_ASSIGN(WebSourceBufferImpl); DISALLOW_COPY_AND_ASSIGN(WebSourceBufferImpl);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment