summaryrefslogtreecommitdiffstats
path: root/media
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 /media
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
Diffstat (limited to 'media')
-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
18 files changed, 111 insertions, 122 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();