Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Unified Diff: media/base/android/media_codec_player_unittest.cc

Issue 1242913004: MediaCodecPlayer implementation (stage 3 - browser seek and surface change) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mtplayer-seek
Patch Set: Rebased, changed DCHECKs. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/android/media_codec_player.cc ('k') | media/base/android/media_codec_video_decoder.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/android/media_codec_player_unittest.cc
diff --git a/media/base/android/media_codec_player_unittest.cc b/media/base/android/media_codec_player_unittest.cc
index f818bac89b74ab4a650725ec41e6f0d889372bed..f8b35f355e5c00febad0041912ac716d2660f020 100644
--- a/media/base/android/media_codec_player_unittest.cc
+++ b/media/base/android/media_codec_player_unittest.cc
@@ -58,7 +58,9 @@ bool AlmostEqual(base::TimeDelta a, base::TimeDelta b, double tolerance_ms) {
class MockMediaPlayerManager : public MediaPlayerManager {
public:
MockMediaPlayerManager()
- : playback_completed_(false), weak_ptr_factory_(this) {}
+ : playback_completed_(false),
+ num_seeks_completed_(0),
+ weak_ptr_factory_(this) {}
~MockMediaPlayerManager() override {}
MediaResourceGetter* GetMediaResourceGetter() override { return nullptr; }
@@ -88,7 +90,9 @@ class MockMediaPlayerManager : public MediaPlayerManager {
void OnMediaInterrupted(int player_id) override {}
void OnBufferingUpdate(int player_id, int percentage) override {}
void OnSeekComplete(int player_id,
- const base::TimeDelta& current_time) override {}
+ const base::TimeDelta& current_time) override {
+ ++num_seeks_completed_;
+ }
void OnError(int player_id, int error) override {}
void OnVideoSizeChanged(int player_id, int width, int height) override {}
void OnAudibleStateChanged(int player_id, bool is_audible_now) override {}
@@ -110,6 +114,7 @@ class MockMediaPlayerManager : public MediaPlayerManager {
bool IsPlaybackBeyondPosition(const base::TimeDelta& pts) const {
return pts_stat_.max() > pts;
}
+ bool IsSeekCompleted() const { return num_seeks_completed_ > 0; }
struct MediaMetadata {
base::TimeDelta duration;
@@ -124,6 +129,7 @@ class MockMediaPlayerManager : public MediaPlayerManager {
private:
bool playback_completed_;
+ int num_seeks_completed_;
base::WeakPtrFactory<MockMediaPlayerManager> weak_ptr_factory_;
@@ -175,13 +181,16 @@ class AudioFactory : public TestDataFactory {
class VideoFactory : public TestDataFactory {
public:
VideoFactory(base::TimeDelta duration)
- : TestDataFactory("h264-320x180-frame-%d", duration, kVideoFramePeriod) {}
+ : TestDataFactory("h264-320x180-frame-%d", duration, kVideoFramePeriod),
+ key_frame_requested_(true) {}
DemuxerConfigs GetConfigs() const override {
return TestDataFactory::CreateVideoConfigs(kCodecH264, duration_,
gfx::Size(320, 180));
}
+ void RequestKeyFrame() { key_frame_requested_ = true; }
+
protected:
void ModifyAccessUnit(int index_in_chunk, AccessUnit* unit) override {
// The frames are taken from High profile and some are B-frames.
@@ -196,7 +205,8 @@ class VideoFactory : public TestDataFactory {
// Swap pts for second and third frames. Make first frame a key frame.
switch (index_in_chunk) {
case 0: // first frame
- unit->is_key_frame = true;
+ unit->is_key_frame = key_frame_requested_;
+ key_frame_requested_ = false;
break;
case 1: // second frame
unit->timestamp += frame_period_;
@@ -211,13 +221,17 @@ class VideoFactory : public TestDataFactory {
break;
}
}
+
+ private:
+ bool key_frame_requested_;
};
// Mock of DemuxerAndroid for testing purpose.
class MockDemuxerAndroid : public DemuxerAndroid {
public:
- MockDemuxerAndroid() : client_(nullptr) {}
+ MockDemuxerAndroid()
+ : client_(nullptr), num_seeks_(0), num_browser_seeks_(0) {}
~MockDemuxerAndroid() override {}
// DemuxerAndroid implementation
@@ -227,15 +241,18 @@ class MockDemuxerAndroid : public DemuxerAndroid {
bool is_browser_seek) override;
// Sets the audio data factory.
- void SetAudioFactory(scoped_ptr<TestDataFactory> factory) {
+ void SetAudioFactory(scoped_ptr<AudioFactory> factory) {
audio_factory_ = factory.Pass();
}
// Sets the video data factory.
- void SetVideoFactory(scoped_ptr<TestDataFactory> factory) {
+ void SetVideoFactory(scoped_ptr<VideoFactory> factory) {
video_factory_ = factory.Pass();
}
+ // Sets the delay in OnDemuxerSeekDone response.
+ void SetSeekDoneDelay(base::TimeDelta delay) { seek_done_delay_ = delay; }
+
// Post DemuxerConfigs to the client (i.e. the player) on correct thread.
void PostConfigs(const DemuxerConfigs& configs);
@@ -245,12 +262,17 @@ class MockDemuxerAndroid : public DemuxerAndroid {
// Conditions to wait for.
bool IsInitialized() const { return client_; }
bool HasPendingConfigs() const { return pending_configs_; }
+ bool ReceivedSeekRequest() const { return num_seeks_ > 0; }
+ bool ReceivedBrowserSeekRequest() const { return num_browser_seeks_ > 0; }
private:
DemuxerAndroidClient* client_;
scoped_ptr<DemuxerConfigs> pending_configs_;
- scoped_ptr<TestDataFactory> audio_factory_;
- scoped_ptr<TestDataFactory> video_factory_;
+ scoped_ptr<AudioFactory> audio_factory_;
+ scoped_ptr<VideoFactory> video_factory_;
+ base::TimeDelta seek_done_delay_;
+ int num_seeks_;
+ int num_browser_seeks_;
DISALLOW_COPY_AND_ASSIGN(MockDemuxerAndroid);
};
@@ -292,16 +314,23 @@ void MockDemuxerAndroid::RequestDemuxerSeek(const base::TimeDelta& time_to_seek,
// Tell data factories to start next chunk with the new timestamp.
if (audio_factory_)
audio_factory_->SeekTo(time_to_seek);
- if (video_factory_)
+ if (video_factory_) {
video_factory_->SeekTo(time_to_seek);
+ video_factory_->RequestKeyFrame();
+ }
+
+ ++num_seeks_;
+ if (is_browser_seek)
+ ++num_browser_seeks_;
// Post OnDemuxerSeekDone() to the player.
DCHECK(client_);
base::TimeDelta reported_seek_time =
is_browser_seek ? time_to_seek : kNoTimestamp();
- GetMediaTaskRunner()->PostTask(
+ GetMediaTaskRunner()->PostDelayedTask(
FROM_HERE, base::Bind(&DemuxerAndroidClient::OnDemuxerSeekDone,
- base::Unretained(client_), reported_seek_time));
+ base::Unretained(client_), reported_seek_time),
+ seek_done_delay_);
}
void MockDemuxerAndroid::PostConfigs(const DemuxerConfigs& configs) {
@@ -347,6 +376,8 @@ class MediaCodecPlayerTest : public testing::Test {
void CreatePlayer();
void SetVideoSurface();
+ void SetVideoSurfaceB();
+ void RemoveVideoSurface();
// Waits for condition to become true or for timeout to expire.
// Returns true if the condition becomes true.
@@ -363,10 +394,15 @@ class MediaCodecPlayerTest : public testing::Test {
const base::TimeDelta& pts,
const base::TimeDelta& timeout = kDefaultTimeout);
+ // Helper method that starts video only stream. Waits till it actually
+ // started.
+ void StartVideoPlayback(base::TimeDelta duration);
+
base::MessageLoop message_loop_;
MockMediaPlayerManager manager_;
MockDemuxerAndroid* demuxer_; // owned by player_
- scoped_refptr<gfx::SurfaceTexture> surface_texture_;
+ scoped_refptr<gfx::SurfaceTexture> surface_texture_a_;
+ scoped_refptr<gfx::SurfaceTexture> surface_texture_b_;
MediaCodecPlayer* player_; // raw pointer due to DeleteOnCorrectThread()
private:
@@ -400,13 +436,26 @@ void MediaCodecPlayerTest::CreatePlayer() {
}
void MediaCodecPlayerTest::SetVideoSurface() {
- surface_texture_ = gfx::SurfaceTexture::Create(0);
- gfx::ScopedJavaSurface surface(surface_texture_.get());
+ surface_texture_a_ = gfx::SurfaceTexture::Create(0);
+ gfx::ScopedJavaSurface surface(surface_texture_a_.get());
+
+ ASSERT_NE(nullptr, player_);
+ player_->SetVideoSurface(surface.Pass());
+}
+
+void MediaCodecPlayerTest::SetVideoSurfaceB() {
+ surface_texture_b_ = gfx::SurfaceTexture::Create(1);
+ gfx::ScopedJavaSurface surface(surface_texture_b_.get());
ASSERT_NE(nullptr, player_);
player_->SetVideoSurface(surface.Pass());
}
+void MediaCodecPlayerTest::RemoveVideoSurface() {
+ player_->SetVideoSurface(gfx::ScopedJavaSurface());
+ surface_texture_a_ = NULL;
+}
+
bool MediaCodecPlayerTest::WaitForCondition(const Predicate& condition,
const base::TimeDelta& timeout) {
// Let the message_loop_ process events.
@@ -444,6 +493,33 @@ bool MediaCodecPlayerTest::WaitForPlaybackBeyondPosition(
timeout);
}
+void MediaCodecPlayerTest::StartVideoPlayback(base::TimeDelta duration) {
+ const base::TimeDelta start_timeout = base::TimeDelta::FromMilliseconds(800);
+
+ demuxer_->SetVideoFactory(
+ scoped_ptr<VideoFactory>(new VideoFactory(duration)));
+
+ CreatePlayer();
+ SetVideoSurface();
+
+ // Wait till the player is initialized on media thread.
+ EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
+ base::Unretained(demuxer_))));
+
+ // Post configuration after the player has been initialized.
+ demuxer_->PostInternalConfigs();
+
+ // Start the player.
+ EXPECT_FALSE(manager_.IsPlaybackStarted());
+ player_->Start();
+
+ // Wait for playback to start.
+ EXPECT_TRUE(
+ WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
+ base::Unretained(&manager_)),
+ start_timeout));
+}
+
TEST_F(MediaCodecPlayerTest, SetAudioConfigsBeforePlayerCreation) {
// Post configuration when there is no player yet.
EXPECT_EQ(nullptr, player_);
@@ -552,23 +628,9 @@ TEST_F(MediaCodecPlayerTest, VideoPlayTillCompletion) {
base::TimeDelta duration = base::TimeDelta::FromMilliseconds(500);
base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500);
- demuxer_->SetVideoFactory(
- scoped_ptr<VideoFactory>(new VideoFactory(duration)));
-
- CreatePlayer();
- SetVideoSurface();
-
- // Wait till the player is initialized on media thread.
- EXPECT_TRUE(WaitForCondition(base::Bind(&MockDemuxerAndroid::IsInitialized,
- base::Unretained(demuxer_))));
-
- // Post configuration after the player has been initialized.
- demuxer_->PostInternalConfigs();
-
- EXPECT_FALSE(manager_.IsPlaybackCompleted());
-
- player_->Start();
+ StartVideoPlayback(duration);
+ // Wait till completion.
EXPECT_TRUE(
WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted,
base::Unretained(&manager_)),
@@ -630,6 +692,10 @@ TEST_F(MediaCodecPlayerTest, AudioSeekAfterStop) {
// Make sure we started from the beginninig
EXPECT_GT(base::TimeDelta::FromMilliseconds(40), manager_.pts_stat_.min());
+
+ // The player should have reported the seek completion to the manager.
+ EXPECT_TRUE(WaitForCondition(base::Bind(
+ &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
}
TEST_F(MediaCodecPlayerTest, AudioSeekThenPlay) {
@@ -660,6 +726,10 @@ TEST_F(MediaCodecPlayerTest, AudioSeekThenPlay) {
// The playback should start at |seek_position|
EXPECT_TRUE(AlmostEqual(seek_position, manager_.pts_stat_.min(), 1));
+
+ // The player should have reported the seek completion to the manager.
+ EXPECT_TRUE(WaitForCondition(base::Bind(
+ &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
}
TEST_F(MediaCodecPlayerTest, AudioSeekThenPlayThenConfig) {
@@ -695,6 +765,10 @@ TEST_F(MediaCodecPlayerTest, AudioSeekThenPlayThenConfig) {
// The playback should start at |seek_position|
EXPECT_TRUE(AlmostEqual(seek_position, manager_.pts_stat_.min(), 1));
+
+ // The player should have reported the seek completion to the manager.
+ EXPECT_TRUE(WaitForCondition(base::Bind(
+ &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
}
TEST_F(MediaCodecPlayerTest, AudioSeekWhilePlaying) {
@@ -740,6 +814,245 @@ TEST_F(MediaCodecPlayerTest, AudioSeekWhilePlaying) {
// i.e. 200 ms.
EXPECT_TRUE(WaitForPlaybackBeyondPosition(base::TimeDelta::FromSeconds(5)));
EXPECT_TRUE(player_->IsPlaying());
+
+ // The player should have reported the seek completion to the manager.
+ EXPECT_TRUE(WaitForCondition(base::Bind(
+ &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
+}
+
+TEST_F(MediaCodecPlayerTest, VideoReplaceSurface) {
+ SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
+
+ base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
+ base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1500);
+
+ StartVideoPlayback(duration);
+
+ // Wait for some time and check statistics.
+ WaitForDelay(base::TimeDelta::FromMilliseconds(200));
+
+ // Make sure we played at least 100 ms.
+ EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
+
+ // Set new video surface without removing the old one.
+ SetVideoSurfaceB();
+
+ // We should receive a browser seek request.
+ EXPECT_TRUE(WaitForCondition(
+ base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest,
+ base::Unretained(demuxer_))));
+
+ // Playback should continue with a new surface. Wait till completion.
+ EXPECT_TRUE(
+ WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackCompleted,
+ base::Unretained(&manager_)),
+ timeout));
+ EXPECT_LE(duration, manager_.pts_stat_.max());
+}
+
+TEST_F(MediaCodecPlayerTest, VideoRemoveAndSetSurface) {
+ SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
+
+ base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
+
+ StartVideoPlayback(duration);
+
+ // Wait for some time and check statistics.
+ WaitForDelay(base::TimeDelta::FromMilliseconds(200));
+
+ // Make sure we played at least 100 ms.
+ EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
+
+ // Remove video surface.
+ RemoveVideoSurface();
+
+ // We should be stuck waiting for the new surface.
+ WaitForDelay(base::TimeDelta::FromMilliseconds(200));
+ EXPECT_FALSE(player_->IsPlaying());
+
+ // Save last PTS and clear statistics.
+ base::TimeDelta max_pts_before_removal = manager_.pts_stat_.max();
+ manager_.pts_stat_.Clear();
+
+ // After clearing statistics we are ready to wait for IsPlaybackStarted again.
+ EXPECT_FALSE(manager_.IsPlaybackStarted());
+
+ // Extra RemoveVideoSurface() should not change anything.
+ RemoveVideoSurface();
+
+ // Set another video surface.
+ SetVideoSurfaceB();
+
+ // We should receive a browser seek request.
+ EXPECT_TRUE(WaitForCondition(
+ base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest,
+ base::Unretained(demuxer_))));
+
+ // Playback should continue with a new surface. Wait till it starts again.
+ base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(800);
+ EXPECT_TRUE(
+ WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
+ base::Unretained(&manager_)),
+ reconfigure_timeout));
+
+ // Timestamps should not go back.
+ EXPECT_LE(max_pts_before_removal, manager_.pts_stat_.max());
+}
+
+TEST_F(MediaCodecPlayerTest, VideoReleaseAndStart) {
+ SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
+
+ base::TimeDelta duration = base::TimeDelta::FromMilliseconds(1000);
+
+ StartVideoPlayback(duration);
+
+ // Wait for some time and check statistics.
+ WaitForDelay(base::TimeDelta::FromMilliseconds(200));
+
+ // Make sure we played at least 100 ms.
+ EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
+
+ // When the user presses Tasks button Chrome calls Pause() and Release().
+ player_->Pause(true);
+ player_->Release();
+
+ // Make sure we are not playing any more.
+ WaitForDelay(base::TimeDelta::FromMilliseconds(200));
+ EXPECT_FALSE(player_->IsPlaying());
+
+ // Save last PTS and clear statistics.
+ base::TimeDelta max_pts_before_backgrounding = manager_.pts_stat_.max();
+ manager_.pts_stat_.Clear();
+
+ // After clearing statistics we are ready to wait for IsPlaybackStarted again.
+ EXPECT_FALSE(manager_.IsPlaybackStarted());
+
+ // Restart.
+ SetVideoSurface();
+ player_->Start();
+
+ // We should receive a browser seek request.
+ EXPECT_TRUE(WaitForCondition(
+ base::Bind(&MockDemuxerAndroid::ReceivedBrowserSeekRequest,
+ base::Unretained(demuxer_))));
+
+ // Wait for playback to start again.
+ base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(800);
+ EXPECT_TRUE(
+ WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
+ base::Unretained(&manager_)),
+ reconfigure_timeout));
+
+ // Timestamps should not go back.
+ EXPECT_LE(max_pts_before_backgrounding, manager_.pts_stat_.max());
+}
+
+TEST_F(MediaCodecPlayerTest, VideoSeekAndRelease) {
+ SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
+
+ base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
+ base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(1000);
+
+ StartVideoPlayback(duration);
+
+ // Wait for some time and check statistics.
+ WaitForDelay(base::TimeDelta::FromMilliseconds(200));
+
+ // Make sure we played at least 100 ms.
+ EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
+
+ // Issue SeekTo() immediately followed by Release().
+ player_->SeekTo(seek_position);
+ player_->Release();
+
+ // Make sure we are not playing any more.
+ WaitForDelay(base::TimeDelta::FromMilliseconds(400));
+ EXPECT_FALSE(player_->IsPlaying());
+
+ // The Release() should not cancel the SeekTo() and we should have received
+ // the seek request by this time.
+ EXPECT_TRUE(demuxer_->ReceivedSeekRequest());
+
+ // The player should have reported the seek completion to the manager.
+ EXPECT_TRUE(WaitForCondition(base::Bind(
+ &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
+
+ // Clear statistics.
+ manager_.pts_stat_.Clear();
+
+ // After clearing statistics we are ready to wait for IsPlaybackStarted again.
+ EXPECT_FALSE(manager_.IsPlaybackStarted());
+
+ // Restart.
+ SetVideoSurface();
+ player_->Start();
+
+ // Wait for playback to start again.
+ base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(800);
+ EXPECT_TRUE(
+ WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
+ base::Unretained(&manager_)),
+ reconfigure_timeout));
+
+ // Timestamps should start at the new seek position
+ EXPECT_LE(seek_position, manager_.pts_stat_.min());
+}
+
+TEST_F(MediaCodecPlayerTest, VideoReleaseWhileWaitingForSeek) {
+ SKIP_TEST_IF_MEDIA_CODEC_BRIDGE_IS_NOT_AVAILABLE();
+
+ base::TimeDelta duration = base::TimeDelta::FromMilliseconds(2000);
+ base::TimeDelta seek_position = base::TimeDelta::FromMilliseconds(1000);
+
+ StartVideoPlayback(duration);
+
+ // Wait for some time and check statistics.
+ WaitForDelay(base::TimeDelta::FromMilliseconds(200));
+
+ // Make sure we played at least 100 ms.
+ EXPECT_LT(base::TimeDelta::FromMilliseconds(100), manager_.pts_stat_.max());
+
+ // Set artificial delay in the OnDemuxerSeekDone response so we can
+ // issue commands while the player is in the STATE_WAITING_FOR_SEEK.
+ demuxer_->SetSeekDoneDelay(base::TimeDelta::FromMilliseconds(100));
+
+ // Issue SeekTo().
+ player_->SeekTo(seek_position);
+
+ // Wait for the seek request to demuxer.
+ EXPECT_TRUE(WaitForCondition(base::Bind(
+ &MockDemuxerAndroid::ReceivedSeekRequest, base::Unretained(demuxer_))));
+
+ // The player is supposed to be in STATE_WAITING_FOR_SEEK. Issue Release().
+ player_->Release();
+
+ // Make sure we are not playing any more.
+ WaitForDelay(base::TimeDelta::FromMilliseconds(400));
+ EXPECT_FALSE(player_->IsPlaying());
+
+ // Clear statistics.
+ manager_.pts_stat_.Clear();
+
+ // After clearing statistics we are ready to wait for IsPlaybackStarted again.
+ EXPECT_FALSE(manager_.IsPlaybackStarted());
+
+ // Restart.
+ SetVideoSurface();
+ player_->Start();
+
+ // Wait for playback to start again.
+ base::TimeDelta reconfigure_timeout = base::TimeDelta::FromMilliseconds(1000);
+ EXPECT_TRUE(
+ WaitForCondition(base::Bind(&MockMediaPlayerManager::IsPlaybackStarted,
+ base::Unretained(&manager_)),
+ reconfigure_timeout));
+
+ // Timestamps should start at the new seek position
+ EXPECT_LE(seek_position, manager_.pts_stat_.min());
+
+ // The player should have reported the seek completion to the manager.
+ EXPECT_TRUE(WaitForCondition(base::Bind(
+ &MockMediaPlayerManager::IsSeekCompleted, base::Unretained(&manager_))));
}
} // namespace media
« no previous file with comments | « media/base/android/media_codec_player.cc ('k') | media/base/android/media_codec_video_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698