summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-22 04:03:38 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-22 04:03:38 +0000
commitf5443ef7d206262bdac14b1f7d26d7dc2e753f35 (patch)
tree23b8fe828dbd77859b33d2049e33125027871e4b
parent1f1057f9b20647adae5807c8bde06cef40cd9e42 (diff)
downloadchromium_src-f5443ef7d206262bdac14b1f7d26d7dc2e753f35.zip
chromium_src-f5443ef7d206262bdac14b1f7d26d7dc2e753f35.tar.gz
chromium_src-f5443ef7d206262bdac14b1f7d26d7dc2e753f35.tar.bz2
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
-rw-r--r--media/base/demuxer.h8
-rw-r--r--media/base/filter_collection.cc7
-rw-r--r--media/base/filter_collection.h7
-rw-r--r--media/base/mock_filters.h4
-rw-r--r--media/base/pipeline.cc16
-rw-r--r--media/base/pipeline.h15
-rw-r--r--media/base/pipeline_unittest.cc8
-rw-r--r--media/filters/chunk_demuxer.h4
-rw-r--r--media/filters/chunk_demuxer_unittest.cc44
-rw-r--r--media/filters/ffmpeg_demuxer.cc24
-rw-r--r--media/filters/ffmpeg_demuxer.h6
-rw-r--r--media/filters/ffmpeg_demuxer_unittest.cc16
-rw-r--r--media/filters/pipeline_integration_test.cc28
-rw-r--r--media/filters/pipeline_integration_test_base.cc14
-rw-r--r--media/filters/pipeline_integration_test_base.h5
-rw-r--r--media/tools/demuxer_bench/demuxer_bench.cc11
-rw-r--r--media/tools/player_x11/player_x11.cc11
-rw-r--r--media/tools/seek_tester/seek_tester.cc5
-rw-r--r--webkit/media/webmediaplayer_impl.cc188
-rw-r--r--webkit/media/webmediaplayer_impl.h15
-rw-r--r--webkit/media/webmediasourceclient_impl.cc3
-rw-r--r--webkit/media/webmediasourceclient_impl.h7
-rw-r--r--webkit/media/websourcebuffer_impl.cc2
-rw-r--r--webkit/media/websourcebuffer_impl.h8
24 files changed, 224 insertions, 232 deletions
diff --git a/media/base/demuxer.h b/media/base/demuxer.h
index 34150af..0a9a15b 100644
--- a/media/base/demuxer.h
+++ b/media/base/demuxer.h
@@ -5,7 +5,6 @@
#ifndef MEDIA_BASE_DEMUXER_H_
#define MEDIA_BASE_DEMUXER_H_
-#include "base/memory/ref_counted.h"
#include "base/time.h"
#include "media/base/data_source.h"
#include "media/base/demuxer_stream.h"
@@ -28,9 +27,10 @@ class MEDIA_EXPORT DemuxerHost : public DataSourceHost {
virtual ~DemuxerHost();
};
-class MEDIA_EXPORT Demuxer : public base::RefCountedThreadSafe<Demuxer> {
+class MEDIA_EXPORT Demuxer {
public:
Demuxer();
+ virtual ~Demuxer();
// Completes initialization of the demuxer.
//
@@ -64,10 +64,6 @@ class MEDIA_EXPORT Demuxer : public base::RefCountedThreadSafe<Demuxer> {
// Returns the starting time for the media file.
virtual base::TimeDelta GetStartTime() const = 0;
- protected:
- friend class base::RefCountedThreadSafe<Demuxer>;
- virtual ~Demuxer();
-
private:
DISALLOW_COPY_AND_ASSIGN(Demuxer);
};
diff --git a/media/base/filter_collection.cc b/media/base/filter_collection.cc
index 911edd5..730835f 100644
--- a/media/base/filter_collection.cc
+++ b/media/base/filter_collection.cc
@@ -4,22 +4,21 @@
#include "media/base/filter_collection.h"
-#include "base/logging.h"
#include "media/base/audio_renderer.h"
#include "media/base/demuxer.h"
#include "media/base/video_renderer.h"
namespace media {
-FilterCollection::FilterCollection() {}
+FilterCollection::FilterCollection() : demuxer_(NULL) {}
FilterCollection::~FilterCollection() {}
-void FilterCollection::SetDemuxer(const scoped_refptr<Demuxer>& demuxer) {
+void FilterCollection::SetDemuxer(Demuxer* demuxer) {
demuxer_ = demuxer;
}
-const scoped_refptr<Demuxer>& FilterCollection::GetDemuxer() {
+Demuxer* FilterCollection::GetDemuxer() {
return demuxer_;
}
diff --git a/media/base/filter_collection.h b/media/base/filter_collection.h
index 07266c6..90ea066 100644
--- a/media/base/filter_collection.h
+++ b/media/base/filter_collection.h
@@ -5,7 +5,6 @@
#ifndef MEDIA_BASE_FILTER_COLLECTION_H_
#define MEDIA_BASE_FILTER_COLLECTION_H_
-#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "media/base/media_export.h"
@@ -25,8 +24,8 @@ class MEDIA_EXPORT FilterCollection {
FilterCollection();
~FilterCollection();
- void SetDemuxer(const scoped_refptr<Demuxer>& demuxer);
- const scoped_refptr<Demuxer>& GetDemuxer();
+ void SetDemuxer(Demuxer* demuxer);
+ Demuxer* GetDemuxer();
void SetAudioRenderer(scoped_ptr<AudioRenderer> audio_renderer);
scoped_ptr<AudioRenderer> GetAudioRenderer();
@@ -35,7 +34,7 @@ class MEDIA_EXPORT FilterCollection {
scoped_ptr<VideoRenderer> GetVideoRenderer();
private:
- scoped_refptr<Demuxer> demuxer_;
+ Demuxer* demuxer_;
scoped_ptr<AudioRenderer> audio_renderer_;
scoped_ptr<VideoRenderer> video_renderer_;
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 56b523a..bd4fd9c 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -27,6 +27,7 @@ namespace media {
class MockDemuxer : public Demuxer {
public:
MockDemuxer();
+ virtual ~MockDemuxer();
// Demuxer implementation.
MOCK_METHOD2(Initialize, void(DemuxerHost* host, const PipelineStatusCB& cb));
@@ -37,9 +38,6 @@ class MockDemuxer : public Demuxer {
MOCK_METHOD1(GetStream, scoped_refptr<DemuxerStream>(DemuxerStream::Type));
MOCK_CONST_METHOD0(GetStartTime, base::TimeDelta());
- protected:
- virtual ~MockDemuxer();
-
private:
DISALLOW_COPY_AND_ASSIGN(MockDemuxer);
};
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
index 5ee835b..1629680 100644
--- a/media/base/pipeline.cc
+++ b/media/base/pipeline.cc
@@ -81,6 +81,7 @@ Pipeline::Pipeline(const scoped_refptr<base::MessageLoopProxy>& message_loop,
audio_ended_(false),
video_ended_(false),
audio_disabled_(false),
+ demuxer_(NULL),
creation_time_(base::Time::Now()) {
media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated));
media_log_->AddEvent(
@@ -584,7 +585,7 @@ void Pipeline::DoSeek(
// Seek demuxer.
bound_fns.Push(base::Bind(
- &Demuxer::Seek, demuxer_, seek_timestamp));
+ &Demuxer::Seek, base::Unretained(demuxer_), seek_timestamp));
// Preroll renderers.
if (audio_renderer_) {
@@ -628,8 +629,10 @@ void Pipeline::DoStop(const PipelineStatusCB& done_cb) {
DCHECK(!pending_callbacks_.get());
SerialRunner::Queue bound_fns;
- if (demuxer_)
- bound_fns.Push(base::Bind(&Demuxer::Stop, demuxer_));
+ if (demuxer_) {
+ bound_fns.Push(base::Bind(
+ &Demuxer::Stop, base::Unretained(demuxer_)));
+ }
if (audio_renderer_) {
bound_fns.Push(base::Bind(
@@ -913,13 +916,9 @@ void Pipeline::InitializeDemuxer(const PipelineStatusCB& done_cb) {
void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) {
DCHECK(message_loop_->BelongsToCurrentThread());
- scoped_refptr<DemuxerStream> stream =
- demuxer_->GetStream(DemuxerStream::AUDIO);
- DCHECK(stream);
-
audio_renderer_ = filter_collection_->GetAudioRenderer();
audio_renderer_->Initialize(
- stream,
+ demuxer_->GetStream(DemuxerStream::AUDIO),
done_cb,
base::Bind(&Pipeline::OnUpdateStatistics, this),
base::Bind(&Pipeline::OnAudioUnderflow, this),
@@ -934,7 +933,6 @@ void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) {
scoped_refptr<DemuxerStream> stream =
demuxer_->GetStream(DemuxerStream::VIDEO);
- DCHECK(stream);
{
// Get an initial natural size so we have something when we signal
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index efd327d..34e36f0 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -442,8 +442,6 @@ class MEDIA_EXPORT Pipeline
// Set to true in DisableAudioRendererTask().
bool audio_disabled_;
- scoped_ptr<FilterCollection> filter_collection_;
-
// Temporary callback used for Start() and Seek().
PipelineStatusCB seek_cb_;
@@ -456,14 +454,17 @@ class MEDIA_EXPORT Pipeline
BufferingStateCB buffering_state_cb_;
base::Closure duration_change_cb_;
- // Renderer references used for setting the volume, playback rate, and
- // determining when playback has finished.
+ // Contains the demuxer and renderers to use when initializing.
+ 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<VideoRenderer> video_renderer_;
- // Demuxer reference used for setting the preload value.
- scoped_refptr<Demuxer> demuxer_;
-
PipelineStatistics statistics_;
// Time of pipeline creation; is non-zero only until the pipeline first
diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
index 988bb80..de938d1 100644
--- a/media/base/pipeline_unittest.cc
+++ b/media/base/pipeline_unittest.cc
@@ -83,9 +83,9 @@ class PipelineTest : public ::testing::Test {
PipelineTest()
: pipeline_(new Pipeline(message_loop_.message_loop_proxy(),
new MediaLog())),
- filter_collection_(new FilterCollection()) {
- demuxer_ = new MockDemuxer();
- filter_collection_->SetDemuxer(demuxer_);
+ filter_collection_(new FilterCollection()),
+ demuxer_(new MockDemuxer()) {
+ filter_collection_->SetDemuxer(demuxer_.get());
video_renderer_ = new MockVideoRenderer();
scoped_ptr<VideoRenderer> video_renderer(video_renderer_);
@@ -295,7 +295,7 @@ class PipelineTest : public ::testing::Test {
scoped_refptr<Pipeline> pipeline_;
scoped_ptr<FilterCollection> filter_collection_;
- scoped_refptr<MockDemuxer> demuxer_;
+ scoped_ptr<MockDemuxer> demuxer_;
MockVideoRenderer* video_renderer_;
MockAudioRenderer* audio_renderer_;
scoped_refptr<StrictMock<MockDemuxerStream> > audio_stream_;
diff --git a/media/filters/chunk_demuxer.h b/media/filters/chunk_demuxer.h
index 94c952e..a5cfc31 100644
--- a/media/filters/chunk_demuxer.h
+++ b/media/filters/chunk_demuxer.h
@@ -45,6 +45,7 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer {
// console.
ChunkDemuxer(const base::Closure& open_cb, const NeedKeyCB& need_key_cb,
const LogCB& log_cb);
+ virtual ~ChunkDemuxer();
// Demuxer implementation.
virtual void Initialize(DemuxerHost* host,
@@ -104,9 +105,6 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer {
bool EndOfStream(PipelineStatus status);
void Shutdown();
- protected:
- virtual ~ChunkDemuxer();
-
private:
enum State {
WAITING_FOR_INIT,
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc
index 0ccd558..b715340 100644
--- a/media/filters/chunk_demuxer_unittest.cc
+++ b/media/filters/chunk_demuxer_unittest.cc
@@ -152,7 +152,7 @@ class ChunkDemuxerTest : public testing::Test {
base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this));
ChunkDemuxer::NeedKeyCB need_key_cb =
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() {
@@ -562,8 +562,7 @@ class ChunkDemuxerTest : public testing::Test {
}
void Read(DemuxerStream::Type type, const DemuxerStream::ReadCB& read_cb) {
- scoped_refptr<DemuxerStream> stream = demuxer_->GetStream(type);
- stream->Read(read_cb);
+ demuxer_->GetStream(type)->Read(read_cb);
message_loop_.RunUntilIdle();
}
@@ -679,27 +678,24 @@ class ChunkDemuxerTest : public testing::Test {
}
void ExpectEndOfStream(DemuxerStream::Type type) {
- scoped_refptr<DemuxerStream> stream = demuxer_->GetStream(type);
EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk, IsEndOfStream()));
- stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone,
- base::Unretained(this)));
+ demuxer_->GetStream(type)->Read(base::Bind(
+ &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
message_loop_.RunUntilIdle();
}
void ExpectRead(DemuxerStream::Type type, int64 timestamp_in_ms) {
- scoped_refptr<DemuxerStream> stream = demuxer_->GetStream(type);
EXPECT_CALL(*this, ReadDone(DemuxerStream::kOk,
HasTimestamp(timestamp_in_ms)));
- stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone,
- base::Unretained(this)));
+ demuxer_->GetStream(type)->Read(base::Bind(
+ &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
message_loop_.RunUntilIdle();
}
void ExpectConfigChanged(DemuxerStream::Type type) {
- scoped_refptr<DemuxerStream> stream = demuxer_->GetStream(type);
EXPECT_CALL(*this, ReadDone(DemuxerStream::kConfigChanged, _));
- stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone,
- base::Unretained(this)));
+ demuxer_->GetStream(type)->Read(base::Bind(
+ &ChunkDemuxerTest::ReadDone, base::Unretained(this)));
message_loop_.RunUntilIdle();
}
@@ -782,7 +778,7 @@ class ChunkDemuxerTest : public testing::Test {
MessageLoop message_loop_;
MockDemuxerHost host_;
- scoped_refptr<ChunkDemuxer> demuxer_;
+ scoped_ptr<ChunkDemuxer> demuxer_;
private:
DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest);
@@ -846,7 +842,7 @@ TEST_F(ChunkDemuxerTest, TestInit) {
}
ShutdownDemuxer();
- demuxer_ = NULL;
+ demuxer_.reset();
}
}
@@ -1090,7 +1086,7 @@ TEST_F(ChunkDemuxerTest, TestEndOfStreamWithNoAppend) {
ShutdownDemuxer();
CheckExpectedRanges("{ }");
demuxer_->RemoveId(kSourceId);
- demuxer_ = NULL;
+ demuxer_.reset();
}
TEST_F(ChunkDemuxerTest, TestEndOfStreamWithNoMediaAppend) {
@@ -1128,7 +1124,7 @@ TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) {
// Read() behavior.
class EndOfStreamHelper {
public:
- explicit EndOfStreamHelper(const scoped_refptr<Demuxer> demuxer)
+ explicit EndOfStreamHelper(Demuxer* demuxer)
: demuxer_(demuxer),
audio_read_done_(false),
video_read_done_(false) {
@@ -1166,7 +1162,7 @@ class EndOfStreamHelper {
*called = true;
}
- scoped_refptr<Demuxer> demuxer_;
+ Demuxer* demuxer_;
bool audio_read_done_;
bool video_read_done_;
@@ -1183,8 +1179,8 @@ TEST_F(ChunkDemuxerTest, TestEndOfStreamWithPendingReads) {
bool audio_read_done_1 = false;
bool video_read_done_1 = false;
- EndOfStreamHelper end_of_stream_helper_1(demuxer_);
- EndOfStreamHelper end_of_stream_helper_2(demuxer_);
+ EndOfStreamHelper end_of_stream_helper_1(demuxer_.get());
+ EndOfStreamHelper end_of_stream_helper_2(demuxer_.get());
ReadAudio(base::Bind(&OnReadDone,
base::TimeDelta::FromMilliseconds(0),
@@ -1219,9 +1215,9 @@ TEST_F(ChunkDemuxerTest, TestReadsAfterEndOfStream) {
bool audio_read_done_1 = false;
bool video_read_done_1 = false;
- EndOfStreamHelper end_of_stream_helper_1(demuxer_);
- EndOfStreamHelper end_of_stream_helper_2(demuxer_);
- EndOfStreamHelper end_of_stream_helper_3(demuxer_);
+ EndOfStreamHelper end_of_stream_helper_1(demuxer_.get());
+ EndOfStreamHelper end_of_stream_helper_2(demuxer_.get());
+ EndOfStreamHelper end_of_stream_helper_3(demuxer_.get());
ReadAudio(base::Bind(&OnReadDone,
base::TimeDelta::FromMilliseconds(0),
@@ -2124,7 +2120,7 @@ TEST_F(ChunkDemuxerTest, TestEndOfStreamDuringSeek) {
GenerateExpectedReads(0, 4);
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.CheckIfReadDonesWereCalled(true);
}
@@ -2185,7 +2181,7 @@ TEST_F(ChunkDemuxerTest, TestConfigChange_Audio) {
DemuxerStream::Status status;
base::TimeDelta last_timestamp;
- scoped_refptr<DemuxerStream> audio =
+ scoped_refptr<DemuxerStream> audio =
demuxer_->GetStream(DemuxerStream::AUDIO);
// Fetch initial audio config and verify it matches what we expect.
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
index 9d5b450..ea0e9c0 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -43,7 +43,6 @@ FFmpegDemuxerStream::FFmpegDemuxerStream(
message_loop_(base::MessageLoopProxy::current()),
stream_(stream),
type_(UNKNOWN),
- stopped_(false),
end_of_stream_(false),
last_packet_timestamp_(kNoTimestamp()),
bitstream_converter_enabled_(false) {
@@ -98,7 +97,7 @@ FFmpegDemuxerStream::FFmpegDemuxerStream(
void FFmpegDemuxerStream::EnqueuePacket(ScopedAVPacket packet) {
DCHECK(message_loop_->BelongsToCurrentThread());
- if (stopped_ || end_of_stream_) {
+ if (!demuxer_ || end_of_stream_) {
NOTREACHED() << "Attempted to enqueue packet on a stopped stream";
return;
}
@@ -178,7 +177,8 @@ void FFmpegDemuxerStream::Stop() {
base::ResetAndReturn(&read_cb_).Run(
DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
}
- stopped_ = true;
+ demuxer_ = NULL;
+ stream_ = NULL;
end_of_stream_ = true;
}
@@ -200,7 +200,7 @@ void FFmpegDemuxerStream::Read(const ReadCB& read_cb) {
// The |demuxer_| may have been destroyed in the pipeline thread.
//
// TODO(scherkus): it would be cleaner to reply with an error message.
- if (stopped_) {
+ if (!demuxer_) {
base::ResetAndReturn(&read_cb_).Run(
DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer());
return;
@@ -228,7 +228,7 @@ const VideoDecoderConfig& FFmpegDemuxerStream::video_decoder_config() {
}
FFmpegDemuxerStream::~FFmpegDemuxerStream() {
- DCHECK(stopped_);
+ DCHECK(!demuxer_);
DCHECK(read_cb_.is_null());
DCHECK(buffer_queue_.IsEmpty());
}
@@ -288,6 +288,7 @@ FFmpegDemuxer::FFmpegDemuxer(
const FFmpegNeedKeyCB& need_key_cb)
: host_(NULL),
message_loop_(message_loop),
+ weak_factory_(this),
blocking_thread_("FFmpegDemuxer"),
pending_read_(false),
pending_seek_(false),
@@ -309,7 +310,8 @@ void FFmpegDemuxer::Stop(const base::Closure& callback) {
DCHECK(message_loop_->BelongsToCurrentThread());
url_protocol_.Abort();
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) {
@@ -331,7 +333,7 @@ void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) {
blocking_thread_.message_loop_proxy(), FROM_HERE,
base::Bind(&av_seek_frame, glue_->format_context(), -1,
time.InMicroseconds(), flags),
- base::Bind(&FFmpegDemuxer::OnSeekFrameDone, this, cb));
+ base::Bind(&FFmpegDemuxer::OnSeekFrameDone, weak_this_, cb));
}
void FFmpegDemuxer::SetPlaybackRate(float playback_rate) {
@@ -354,6 +356,7 @@ void FFmpegDemuxer::Initialize(DemuxerHost* host,
const PipelineStatusCB& status_cb) {
DCHECK(message_loop_->BelongsToCurrentThread());
host_ = host;
+ weak_this_ = weak_factory_.GetWeakPtr();
// TODO(scherkus): DataSource should have a host by this point,
// see http://crbug.com/122071
@@ -372,7 +375,7 @@ void FFmpegDemuxer::Initialize(DemuxerHost* host,
base::PostTaskAndReplyWithResult(
blocking_thread_.message_loop_proxy(), FROM_HERE,
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(
@@ -451,7 +454,7 @@ void FFmpegDemuxer::OnOpenContextDone(const PipelineStatusCB& status_cb,
blocking_thread_.message_loop_proxy(), FROM_HERE,
base::Bind(&avformat_find_stream_info, glue_->format_context(),
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,
@@ -608,7 +611,8 @@ void FFmpegDemuxer::ReadFrameIfNeeded() {
base::PostTaskAndReplyWithResult(
blocking_thread_.message_loop_proxy(), FROM_HERE,
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) {
diff --git a/media/filters/ffmpeg_demuxer.h b/media/filters/ffmpeg_demuxer.h
index 87085c7..18eed0f 100644
--- a/media/filters/ffmpeg_demuxer.h
+++ b/media/filters/ffmpeg_demuxer.h
@@ -119,7 +119,6 @@ class FFmpegDemuxerStream : public DemuxerStream {
VideoDecoderConfig video_config_;
Type type_;
base::TimeDelta duration_;
- bool stopped_;
bool end_of_stream_;
base::TimeDelta last_packet_timestamp_;
Ranges<base::TimeDelta> buffered_ranges_;
@@ -140,6 +139,7 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer {
FFmpegDemuxer(const scoped_refptr<base::MessageLoopProxy>& message_loop,
const scoped_refptr<DataSource>& data_source,
const FFmpegNeedKeyCB& need_key_cb);
+ virtual ~FFmpegDemuxer();
// Demuxer implementation.
virtual void Initialize(DemuxerHost* host,
@@ -165,8 +165,6 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer {
// To allow tests access to privates.
friend class FFmpegDemuxerTest;
- virtual ~FFmpegDemuxer();
-
// FFmpeg callbacks during initialization.
void OnOpenContextDone(const PipelineStatusCB& status_cb, bool result);
void OnFindStreamInfoDone(const PipelineStatusCB& status_cb, int result);
@@ -199,6 +197,8 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer {
DemuxerHost* host_;
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.
base::Thread blocking_thread_;
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc
index 4fccfb9..35c950d 100644
--- a/media/filters/ffmpeg_demuxer_unittest.cc
+++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -69,8 +69,6 @@ class FFmpegDemuxerTest : public testing::Test {
demuxer_->Stop(MessageLoop::QuitWhenIdleClosure());
message_loop_.Run();
}
-
- demuxer_ = NULL;
}
void CreateDemuxer(const std::string& name) {
@@ -84,9 +82,8 @@ class FFmpegDemuxerTest : public testing::Test {
media::FFmpegNeedKeyCB need_key_cb =
base::Bind(&FFmpegDemuxerTest::NeedKeyCB, base::Unretained(this));
- demuxer_ = new FFmpegDemuxer(message_loop_.message_loop_proxy(),
- data_source_,
- need_key_cb);
+ demuxer_.reset(new FFmpegDemuxer(
+ message_loop_.message_loop_proxy(), data_source_, need_key_cb));
}
MOCK_METHOD1(CheckPoint, void(int v));
@@ -148,12 +145,12 @@ class FFmpegDemuxerTest : public testing::Test {
bool IsStreamStopped(DemuxerStream::Type type) {
DemuxerStream* stream = demuxer_->GetStream(type);
CHECK(stream);
- return static_cast<FFmpegDemuxerStream*>(stream)->stopped_;
+ return !static_cast<FFmpegDemuxerStream*>(stream)->demuxer_;
}
// Fixture members.
scoped_refptr<FileDataSource> data_source_;
- scoped_refptr<FFmpegDemuxer> demuxer_;
+ scoped_ptr<FFmpegDemuxer> demuxer_;
StrictMock<MockDemuxerHost> host_;
MessageLoop message_loop_;
@@ -508,9 +505,8 @@ TEST_F(FFmpegDemuxerTest, StreamReadAfterStopAndDemuxerDestruction) {
EXPECT_CALL(*callback, OnDelete());
EXPECT_CALL(*this, CheckPoint(1));
- // Release the reference to the demuxer. This should also destroy it.
- demuxer_ = NULL;
- // |audio| now has a demuxer_ pointer to invalid memory.
+ // Destroy the demuxer. |audio| now has a demuxer_ pointer to invalid memory.
+ demuxer_.reset();
// Attempt the read...
audio->Read(base::Bind(&MockReadCB::Run, callback));
diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc
index ef5694d..c29f987 100644
--- a/media/filters/pipeline_integration_test.cc
+++ b/media/filters/pipeline_integration_test.cc
@@ -11,6 +11,7 @@
#include "media/base/decoder_buffer.h"
#include "media/base/test_data_util.h"
#include "media/crypto/aes_decryptor.h"
+#include "media/filters/chunk_demuxer.h"
using testing::AtMost;
@@ -230,11 +231,14 @@ class MockMediaSource {
: file_path_(GetTestDataFilePath(filename)),
current_position_(0),
initial_append_size_(initial_append_size),
- mimetype_(mimetype) {
- chunk_demuxer_ = new ChunkDemuxer(
- base::Bind(&MockMediaSource::DemuxerOpened, base::Unretained(this)),
- base::Bind(&MockMediaSource::DemuxerNeedKey, base::Unretained(this)),
- LogCB());
+ mimetype_(mimetype),
+ chunk_demuxer_(new ChunkDemuxer(
+ base::Bind(&MockMediaSource::DemuxerOpened,
+ base::Unretained(this)),
+ base::Bind(&MockMediaSource::DemuxerNeedKey,
+ base::Unretained(this)),
+ LogCB())),
+ owned_chunk_demuxer_(chunk_demuxer_) {
file_data_ = ReadTestDataFile(filename);
@@ -247,7 +251,7 @@ class 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) {
need_key_cb_ = need_key_cb;
@@ -266,7 +270,7 @@ class MockMediaSource {
}
void AppendData(int size) {
- DCHECK(chunk_demuxer_.get());
+ DCHECK(chunk_demuxer_);
DCHECK_LT(current_position_, file_data_->GetDataSize());
DCHECK_LE(current_position_ + size, file_data_->GetDataSize());
chunk_demuxer_->AppendData(
@@ -286,7 +290,7 @@ class MockMediaSource {
}
void Abort() {
- if (!chunk_demuxer_.get())
+ if (!chunk_demuxer_)
return;
chunk_demuxer_->Shutdown();
chunk_demuxer_ = NULL;
@@ -326,7 +330,8 @@ class MockMediaSource {
int current_position_;
int initial_append_size_;
std::string mimetype_;
- scoped_refptr<ChunkDemuxer> chunk_demuxer_;
+ ChunkDemuxer* chunk_demuxer_;
+ scoped_ptr<Demuxer> owned_chunk_demuxer_;
NeedKeyCB need_key_cb_;
};
@@ -340,7 +345,7 @@ class PipelineIntegrationTest
EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted))
.Times(AtMost(1));
pipeline_->Start(
- CreateFilterCollection(source->demuxer(), NULL),
+ CreateFilterCollection(source->GetDemuxer(), NULL),
base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
QuitOnStatusCB(PIPELINE_OK),
@@ -359,7 +364,8 @@ class PipelineIntegrationTest
EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted))
.Times(AtMost(1));
pipeline_->Start(
- CreateFilterCollection(source->demuxer(), encrypted_media->decryptor()),
+ CreateFilterCollection(source->GetDemuxer(),
+ encrypted_media->decryptor()),
base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
QuitOnStatusCB(PIPELINE_OK),
diff --git a/media/filters/pipeline_integration_test_base.cc b/media/filters/pipeline_integration_test_base.cc
index 0be9861..c138afb 100644
--- a/media/filters/pipeline_integration_test_base.cc
+++ b/media/filters/pipeline_integration_test_base.cc
@@ -210,19 +210,19 @@ PipelineIntegrationTestBase::CreateFilterCollection(
media::FFmpegNeedKeyCB need_key_cb =
base::Bind(&PipelineIntegrationTestBase::DemuxerNeedKeyCB,
base::Unretained(this));
- return CreateFilterCollection(
- new FFmpegDemuxer(message_loop_.message_loop_proxy(),
- data_source,
- need_key_cb),
- decryptor);
+ scoped_ptr<Demuxer> demuxer(new FFmpegDemuxer(
+ message_loop_.message_loop_proxy(), data_source, need_key_cb));
+ return CreateFilterCollection(demuxer.Pass(), decryptor);
}
scoped_ptr<FilterCollection>
PipelineIntegrationTestBase::CreateFilterCollection(
- const scoped_refptr<Demuxer>& demuxer,
+ scoped_ptr<Demuxer> demuxer,
Decryptor* decryptor) {
+ demuxer_ = demuxer.Pass();
+
scoped_ptr<FilterCollection> collection(new FilterCollection());
- collection->SetDemuxer(demuxer);
+ collection->SetDemuxer(demuxer_.get());
ScopedVector<VideoDecoder> video_decoders;
video_decoders.push_back(
diff --git a/media/filters/pipeline_integration_test_base.h b/media/filters/pipeline_integration_test_base.h
index 034d23f..3be1a69 100644
--- a/media/filters/pipeline_integration_test_base.h
+++ b/media/filters/pipeline_integration_test_base.h
@@ -10,7 +10,6 @@
#include "media/audio/null_audio_sink.h"
#include "media/base/filter_collection.h"
#include "media/base/pipeline.h"
-#include "media/filters/chunk_demuxer.h"
#include "media/filters/video_renderer_base.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -21,6 +20,7 @@ class FilePath;
namespace media {
class Decryptor;
+class Demuxer;
// Empty MD5 hash string. Used to verify empty audio or video tracks.
extern const char kNullHash[];
@@ -74,6 +74,7 @@ class PipelineIntegrationTestBase {
MessageLoop message_loop_;
base::MD5Context md5_context_;
bool hashing_enabled_;
+ scoped_ptr<Demuxer> demuxer_;
scoped_refptr<Pipeline> pipeline_;
scoped_refptr<NullAudioSink> audio_sink_;
bool ended_;
@@ -94,7 +95,7 @@ class PipelineIntegrationTestBase {
void OnError(PipelineStatus status);
void QuitAfterCurrentTimeTask(const base::TimeDelta& quit_time);
scoped_ptr<FilterCollection> CreateFilterCollection(
- const scoped_refptr<Demuxer>& demuxer, Decryptor* decryptor);
+ scoped_ptr<Demuxer> demuxer, Decryptor* decryptor);
void SetDecryptor(Decryptor* decryptor,
const DecryptorReadyCB& decryptor_ready_cb);
void OnVideoRendererPaint(const scoped_refptr<VideoFrame>& frame);
diff --git a/media/tools/demuxer_bench/demuxer_bench.cc b/media/tools/demuxer_bench/demuxer_bench.cc
index 7821695..40b79b2 100644
--- a/media/tools/demuxer_bench/demuxer_bench.cc
+++ b/media/tools/demuxer_bench/demuxer_bench.cc
@@ -54,7 +54,7 @@ typedef std::vector<scoped_refptr<media::DemuxerStream> > Streams;
// present in |demuxer| in as-close-to-monotonically-increasing timestamp order.
class StreamReader {
public:
- explicit StreamReader(const scoped_refptr<media::Demuxer>& demuxer);
+ explicit StreamReader(media::Demuxer* demuxer);
~StreamReader();
// Performs a single step read.
@@ -83,7 +83,7 @@ class StreamReader {
DISALLOW_COPY_AND_ASSIGN(StreamReader);
};
-StreamReader::StreamReader(const scoped_refptr<media::Demuxer> &demuxer) {
+StreamReader::StreamReader(media::Demuxer* demuxer) {
scoped_refptr<media::DemuxerStream> stream;
stream = demuxer->GetStream(media::DemuxerStream::AUDIO);
if (stream) {
@@ -183,15 +183,14 @@ int main(int argc, char** argv) {
CHECK(data_source->Initialize(file_path));
media::FFmpegNeedKeyCB need_key_cb = base::Bind(&NeedKey);
- scoped_refptr<media::FFmpegDemuxer> demuxer =
- new media::FFmpegDemuxer(message_loop.message_loop_proxy(), data_source,
- need_key_cb);
+ scoped_ptr<media::FFmpegDemuxer> demuxer(new media::FFmpegDemuxer(
+ message_loop.message_loop_proxy(), data_source, need_key_cb));
demuxer->Initialize(&demuxer_host, base::Bind(
&QuitLoopWithStatus, &message_loop));
message_loop.Run();
- StreamReader stream_reader(demuxer);
+ StreamReader stream_reader(demuxer.get());
// Benchmark.
base::TimeTicks start = base::TimeTicks::HighResNow();
diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc
index 7b029fc..c83e9ad 100644
--- a/media/tools/player_x11/player_x11.cc
+++ b/media/tools/player_x11/player_x11.cc
@@ -102,7 +102,7 @@ static void NeedKey(const std::string& type, scoped_ptr<uint8[]> init_data,
// TODO(vrk): Re-enabled audio. (crbug.com/112159)
bool InitPipeline(const scoped_refptr<base::MessageLoopProxy>& message_loop,
- const scoped_refptr<media::DataSource>& data_source,
+ media::Demuxer* demuxer,
const PaintCB& paint_cb,
bool /* enable_audio */,
scoped_refptr<media::Pipeline>* pipeline,
@@ -110,10 +110,7 @@ bool InitPipeline(const scoped_refptr<base::MessageLoopProxy>& message_loop,
// Create our filter factories.
scoped_ptr<media::FilterCollection> collection(
new media::FilterCollection());
- media::FFmpegNeedKeyCB need_key_cb = base::Bind(&NeedKey);
- collection->SetDemuxer(new media::FFmpegDemuxer(message_loop, data_source,
- need_key_cb));
-
+ collection->SetDemuxer(demuxer);
ScopedVector<media::VideoDecoder> video_decoders;
video_decoders.push_back(new media::FFmpegVideoDecoder(message_loop));
@@ -281,8 +278,10 @@ int main(int argc, char** argv) {
scoped_refptr<media::DataSource> data_source(
new DataSourceLogger(CreateFileDataSource(filename),
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"),
&pipeline, &message_loop)) {
// Main loop of the application.
diff --git a/media/tools/seek_tester/seek_tester.cc b/media/tools/seek_tester/seek_tester.cc
index f224e2c..d1d90ba 100644
--- a/media/tools/seek_tester/seek_tester.cc
+++ b/media/tools/seek_tester/seek_tester.cc
@@ -73,9 +73,8 @@ int main(int argc, char** argv) {
MessageLoop loop;
media::PipelineStatusCB quitter = base::Bind(&QuitMessageLoop, &loop);
media::FFmpegNeedKeyCB need_key_cb = base::Bind(&NeedKey);
- scoped_refptr<media::FFmpegDemuxer> demuxer(
- new media::FFmpegDemuxer(loop.message_loop_proxy(), file_data_source,
- need_key_cb));
+ scoped_ptr<media::FFmpegDemuxer> demuxer(new media::FFmpegDemuxer(
+ loop.message_loop_proxy(), file_data_source, need_key_cb));
demuxer->Initialize(&host, quitter);
loop.Run();
diff --git a/webkit/media/webmediaplayer_impl.cc b/webkit/media/webmediaplayer_impl.cc
index 20d3678..7917b66 100644
--- a/webkit/media/webmediaplayer_impl.cc
+++ b/webkit/media/webmediaplayer_impl.cc
@@ -153,6 +153,7 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(
is_local_source_(false),
supports_save_(true),
starting_(false),
+ chunk_demuxer_(NULL),
pending_repaint_(false),
video_frame_provider_client_(NULL) {
media_log_->AddEvent(
@@ -266,18 +267,11 @@ void WebMediaPlayerImpl::load(const WebKit::WebURL& url, CORSMode cors_mode) {
void WebMediaPlayerImpl::load(const WebKit::WebURL& url,
WebKit::WebMediaSource* media_source,
CORSMode cors_mode) {
- scoped_ptr<WebKit::WebMediaSource> ms(media_source);
LoadSetup(url);
// 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;
- StartPipeline();
+ StartPipeline(media_source);
}
void WebMediaPlayerImpl::LoadSetup(const WebKit::WebURL& url) {
@@ -1122,7 +1116,7 @@ void WebMediaPlayerImpl::DataSourceInitialized(const GURL& gurl, bool success) {
return;
}
- StartPipeline();
+ StartPipeline(NULL);
}
void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) {
@@ -1136,10 +1130,97 @@ void WebMediaPlayerImpl::NotifyDownloading(bool 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;
pipeline_->Start(
- BuildFilterCollection(),
+ filter_collection.Pass(),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError),
BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineSeek),
@@ -1175,8 +1256,10 @@ void WebMediaPlayerImpl::Destroy() {
// Abort any pending IO so stopping the pipeline doesn't get blocked.
if (data_source_)
data_source_->Abort();
- if (chunk_demuxer_)
+ if (chunk_demuxer_) {
chunk_demuxer_->Shutdown();
+ chunk_demuxer_ = NULL;
+ }
if (gpu_factories_) {
gpu_factories_->Abort();
@@ -1200,7 +1283,7 @@ void WebMediaPlayerImpl::Destroy() {
// Release any final references now that everything has stopped.
data_source_ = NULL;
- chunk_demuxer_ = NULL;
+ demuxer_.reset();
}
WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() {
@@ -1250,83 +1333,4 @@ void WebMediaPlayerImpl::FrameReady(
&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
diff --git a/webkit/media/webmediaplayer_impl.h b/webkit/media/webmediaplayer_impl.h
index 46f9985..6b7cd33 100644
--- a/webkit/media/webmediaplayer_impl.h
+++ b/webkit/media/webmediaplayer_impl.h
@@ -53,6 +53,7 @@ class MessageLoopProxy;
namespace media {
class ChunkDemuxer;
+class FFmpegDemuxer;
class MediaLog;
}
@@ -230,7 +231,9 @@ class WebMediaPlayerImpl
void NotifyDownloading(bool is_downloading);
// 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
// they've changed.
@@ -272,10 +275,6 @@ class WebMediaPlayerImpl
// painted.
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_;
// TODO(hclam): get rid of these members and read from the pipeline directly.
@@ -349,8 +348,12 @@ class WebMediaPlayerImpl
// These two are mutually exclusive:
// |data_source_| is used for regular 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<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
// through GenerateKeyRequest() directly from WebKit.
diff --git a/webkit/media/webmediasourceclient_impl.cc b/webkit/media/webmediasourceclient_impl.cc
index 204f0d0..3eb36f4 100644
--- a/webkit/media/webmediasourceclient_impl.cc
+++ b/webkit/media/webmediasourceclient_impl.cc
@@ -25,8 +25,7 @@ COMPILE_ASSERT_MATCHING_STATUS_ENUM(AddStatusReachedIdLimit, kReachedIdLimit);
#undef COMPILE_ASSERT_MATCHING_STATUS_ENUM
WebMediaSourceClientImpl::WebMediaSourceClientImpl(
- const scoped_refptr<media::ChunkDemuxer>& demuxer,
- media::LogCB log_cb)
+ media::ChunkDemuxer* demuxer, media::LogCB log_cb)
: demuxer_(demuxer),
log_cb_(log_cb) {
DCHECK(demuxer_);
diff --git a/webkit/media/webmediasourceclient_impl.h b/webkit/media/webmediasourceclient_impl.h
index 1aa0f6e..3dad1dc 100644
--- a/webkit/media/webmediasourceclient_impl.h
+++ b/webkit/media/webmediasourceclient_impl.h
@@ -8,7 +8,6 @@
#include <string>
#include <vector>
-#include "base/memory/ref_counted.h"
#include "media/base/media_log.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaSourceClient.h"
@@ -20,9 +19,7 @@ namespace webkit_media {
class WebMediaSourceClientImpl : public WebKit::WebMediaSourceClient {
public:
- explicit WebMediaSourceClientImpl(
- const scoped_refptr<media::ChunkDemuxer>& demuxer,
- media::LogCB log_cb);
+ WebMediaSourceClientImpl(media::ChunkDemuxer* demuxer, media::LogCB log_cb);
virtual ~WebMediaSourceClientImpl();
// WebKit::WebMediaSourceClient implementation.
@@ -35,7 +32,7 @@ class WebMediaSourceClientImpl : public WebKit::WebMediaSourceClient {
virtual void endOfStream(EndOfStreamStatus status) OVERRIDE;
private:
- scoped_refptr<media::ChunkDemuxer> demuxer_;
+ media::ChunkDemuxer* demuxer_; // Owned by WebMediaPlayerImpl.
media::LogCB log_cb_;
DISALLOW_COPY_AND_ASSIGN(WebMediaSourceClientImpl);
diff --git a/webkit/media/websourcebuffer_impl.cc b/webkit/media/websourcebuffer_impl.cc
index de03e5a..5e1bf0b 100644
--- a/webkit/media/websourcebuffer_impl.cc
+++ b/webkit/media/websourcebuffer_impl.cc
@@ -9,7 +9,7 @@
namespace webkit_media {
WebSourceBufferImpl::WebSourceBufferImpl(
- const std::string& id, scoped_refptr<media::ChunkDemuxer> demuxer)
+ const std::string& id, media::ChunkDemuxer* demuxer)
: id_(id),
demuxer_(demuxer) {
DCHECK(demuxer_);
diff --git a/webkit/media/websourcebuffer_impl.h b/webkit/media/websourcebuffer_impl.h
index e4718f3..6d8bd85 100644
--- a/webkit/media/websourcebuffer_impl.h
+++ b/webkit/media/websourcebuffer_impl.h
@@ -7,7 +7,8 @@
#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"
namespace media {
@@ -18,8 +19,7 @@ namespace webkit_media {
class WebSourceBufferImpl : public WebKit::WebSourceBuffer {
public:
- WebSourceBufferImpl(const std::string& id,
- scoped_refptr<media::ChunkDemuxer> demuxer);
+ WebSourceBufferImpl(const std::string& id, media::ChunkDemuxer* demuxer);
virtual ~WebSourceBufferImpl();
// WebKit::WebSourceBuffer implementation.
@@ -31,7 +31,7 @@ class WebSourceBufferImpl : public WebKit::WebSourceBuffer {
private:
std::string id_;
- scoped_refptr<media::ChunkDemuxer> demuxer_;
+ media::ChunkDemuxer* demuxer_; // Owned by WebMediaPlayerImpl.
DISALLOW_COPY_AND_ASSIGN(WebSourceBufferImpl);
};