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

Unified Diff: chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc

Issue 1372393007: [Chromecast] Upgrade to new CMA backend API (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Remove gyp target for backend adapter Created 5 years, 2 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
Index: chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
diff --git a/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc b/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
index 84004a87363f4e98677a2e428dd06da6e1509fab..764c3cc8883d8eef12c2c12ad26535a7a4a782bb 100644
--- a/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
+++ b/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
@@ -20,18 +20,15 @@
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "chromecast/base/task_runner_impl.h"
+#include "chromecast/media/cma/base/cast_decoder_buffer_impl.h"
#include "chromecast/media/cma/base/decoder_buffer_adapter.h"
#include "chromecast/media/cma/base/decoder_config_adapter.h"
#include "chromecast/media/cma/test/frame_segmenter_for_test.h"
-#include "chromecast/media/cma/test/media_component_device_feeder_for_test.h"
#include "chromecast/public/cast_media_shlib.h"
-#include "chromecast/public/media/audio_pipeline_device.h"
#include "chromecast/public/media/cast_decoder_buffer.h"
#include "chromecast/public/media/decoder_config.h"
-#include "chromecast/public/media/media_clock_device.h"
#include "chromecast/public/media/media_pipeline_backend.h"
#include "chromecast/public/media/media_pipeline_device_params.h"
-#include "chromecast/public/media/video_pipeline_device.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/decoder_buffer.h"
#include "media/base/video_decoder_config.h"
@@ -42,9 +39,6 @@ namespace media {
namespace {
-typedef ScopedVector<MediaComponentDeviceFeederForTest>::iterator
- ComponentDeviceIterator;
-
const base::TimeDelta kMonitorLoopDelay = base::TimeDelta::FromMilliseconds(20);
base::FilePath GetTestDataFilePath(const std::string& name) {
@@ -59,7 +53,8 @@ base::FilePath GetTestDataFilePath(const std::string& name) {
} // namespace
-class AudioVideoPipelineDeviceTest : public testing::Test {
+class AudioVideoPipelineDeviceTest : public testing::Test,
+ public MediaPipelineBackend::Delegate {
public:
struct PauseInfo {
PauseInfo() {}
@@ -96,25 +91,31 @@ class AudioVideoPipelineDeviceTest : public testing::Test {
void Start();
+ // MediaPipelineBackend::Delegate implementation:
+ void OnVideoResolutionChanged(MediaPipelineBackend::VideoDecoder* decoder,
+ const Size& size) override {}
+ void OnPushBufferComplete(MediaPipelineBackend::Decoder* decoder,
+ MediaPipelineBackend::BufferStatus status) override;
+ void OnEndOfStream(MediaPipelineBackend::Decoder* decoder) override;
+ void OnDecoderError(MediaPipelineBackend::Decoder* decoder) override;
+
private:
void Initialize();
void LoadAudioStream(const std::string& filename);
void LoadVideoStream(const std::string& filename, bool raw_h264);
+ void FeedAudioBuffer();
+ void FeedVideoBuffer();
+
void MonitorLoop();
void OnPauseCompleted();
- void OnEos(MediaComponentDeviceFeederForTest* device_feeder);
-
scoped_ptr<TaskRunnerImpl> task_runner_;
scoped_ptr<MediaPipelineBackend> backend_;
- MediaClockDevice* media_clock_device_;
-
- // Devices to feed
- ScopedVector<MediaComponentDeviceFeederForTest>
- component_device_feeders_;
+ scoped_ptr<CastDecoderBufferImpl> backend_audio_buffer_;
+ scoped_ptr<CastDecoderBufferImpl> backend_video_buffer_;
// Current media time.
base::TimeDelta pause_time_;
@@ -123,11 +124,23 @@ class AudioVideoPipelineDeviceTest : public testing::Test {
std::vector<PauseInfo> pause_pattern_;
int pause_pattern_idx_;
+ BufferList audio_buffers_;
+ BufferList video_buffers_;
+
+ MediaPipelineBackend::AudioDecoder* audio_decoder_;
+ MediaPipelineBackend::VideoDecoder* video_decoder_;
+ bool audio_feeding_completed_;
+ bool video_feeding_completed_;
+
DISALLOW_COPY_AND_ASSIGN(AudioVideoPipelineDeviceTest);
};
AudioVideoPipelineDeviceTest::AudioVideoPipelineDeviceTest()
- : pause_pattern_() {
+ : pause_pattern_(),
+ audio_decoder_(nullptr),
+ video_decoder_(nullptr),
+ audio_feeding_completed_(true),
+ video_feeding_completed_(true) {
}
AudioVideoPipelineDeviceTest::~AudioVideoPipelineDeviceTest() {
@@ -147,6 +160,8 @@ void AudioVideoPipelineDeviceTest::ConfigureForAudioOnly(
const std::string& filename) {
Initialize();
LoadAudioStream(filename);
+ bool success = backend_->Initialize(this);
+ ASSERT_TRUE(success);
}
void AudioVideoPipelineDeviceTest::ConfigureForVideoOnly(
@@ -154,6 +169,8 @@ void AudioVideoPipelineDeviceTest::ConfigureForVideoOnly(
bool raw_h264) {
Initialize();
LoadVideoStream(filename, raw_h264);
+ bool success = backend_->Initialize(this);
+ ASSERT_TRUE(success);
}
void AudioVideoPipelineDeviceTest::ConfigureForFile(
@@ -161,38 +178,32 @@ void AudioVideoPipelineDeviceTest::ConfigureForFile(
Initialize();
LoadVideoStream(filename, false /* raw_h264 */);
LoadAudioStream(filename);
+ bool success = backend_->Initialize(this);
+ ASSERT_TRUE(success);
}
void AudioVideoPipelineDeviceTest::LoadAudioStream(
const std::string& filename) {
base::FilePath file_path = GetTestDataFilePath(filename);
DemuxResult demux_result = FFmpegDemuxForTest(file_path, true /* audio */);
- BufferList frames = demux_result.frames;
- AudioPipelineDevice* audio_pipeline_device = backend_->GetAudio();
+ audio_buffers_ = demux_result.frames;
+ audio_decoder_ = backend_->CreateAudioDecoder();
+ audio_feeding_completed_ = false;
- bool success = audio_pipeline_device->SetConfig(
- DecoderConfigAdapter::ToCastAudioConfig(kPrimary,
- demux_result.audio_config));
+ bool success =
+ audio_decoder_->SetConfig(DecoderConfigAdapter::ToCastAudioConfig(
+ kPrimary, demux_result.audio_config));
ASSERT_TRUE(success);
- VLOG(2) << "Got " << frames.size() << " audio input frames";
-
- frames.push_back(
- scoped_refptr<DecoderBufferBase>(
- new DecoderBufferAdapter(::media::DecoderBuffer::CreateEOSBuffer())));
+ VLOG(2) << "Got " << audio_buffers_.size() << " audio input frames";
- MediaComponentDeviceFeederForTest* device_feeder =
- new MediaComponentDeviceFeederForTest(audio_pipeline_device, frames);
- device_feeder->Initialize(base::Bind(&AudioVideoPipelineDeviceTest::OnEos,
- base::Unretained(this),
- device_feeder));
- component_device_feeders_.push_back(device_feeder);
+ audio_buffers_.push_back(scoped_refptr<DecoderBufferBase>(
+ new DecoderBufferAdapter(::media::DecoderBuffer::CreateEOSBuffer())));
}
void AudioVideoPipelineDeviceTest::LoadVideoStream(const std::string& filename,
bool raw_h264) {
- BufferList frames;
VideoConfig video_config;
if (raw_h264) {
@@ -200,7 +211,8 @@ void AudioVideoPipelineDeviceTest::LoadVideoStream(const std::string& filename,
base::MemoryMappedFile video_stream;
ASSERT_TRUE(video_stream.Initialize(file_path))
<< "Couldn't open stream file: " << file_path.MaybeAsASCII();
- frames = H264SegmenterForTest(video_stream.data(), video_stream.length());
+ video_buffers_ =
+ H264SegmenterForTest(video_stream.data(), video_stream.length());
// TODO(erickung): Either pull data from stream or make caller specify value
video_config.codec = kCodecH264;
@@ -211,59 +223,167 @@ void AudioVideoPipelineDeviceTest::LoadVideoStream(const std::string& filename,
base::FilePath file_path = GetTestDataFilePath(filename);
DemuxResult demux_result = FFmpegDemuxForTest(file_path,
/*audio*/ false);
- frames = demux_result.frames;
+ video_buffers_ = demux_result.frames;
video_config = DecoderConfigAdapter::ToCastVideoConfig(
kPrimary, demux_result.video_config);
}
- VideoPipelineDevice* video_pipeline_device = backend_->GetVideo();
-
- // Set configuration.
- bool success = video_pipeline_device->SetConfig(video_config);
+ video_decoder_ = backend_->CreateVideoDecoder();
+ video_feeding_completed_ = false;
+ bool success = video_decoder_->SetConfig(video_config);
ASSERT_TRUE(success);
- VLOG(2) << "Got " << frames.size() << " video input frames";
+ VLOG(2) << "Got " << video_buffers_.size() << " video input frames";
+
+ video_buffers_.push_back(scoped_refptr<DecoderBufferBase>(
+ new DecoderBufferAdapter(::media::DecoderBuffer::CreateEOSBuffer())));
+}
+
+void AudioVideoPipelineDeviceTest::FeedAudioBuffer() {
+ // Possibly feed one frame
+ DCHECK(!audio_buffers_.empty());
+ if (audio_feeding_completed_)
+ return;
+
+ scoped_refptr<DecoderBufferBase> buffer = audio_buffers_.front();
+ if (backend_audio_buffer_)
+ backend_audio_buffer_->set_buffer(buffer);
+ else
+ backend_audio_buffer_.reset(new CastDecoderBufferImpl(buffer));
halliwell 2015/10/14 15:02:37 same as other file: a no-args constructor for Cast
kmackay 2015/10/14 21:27:26 Done.
+
+ MediaPipelineBackend::BufferStatus status =
+ audio_decoder_->PushBuffer(nullptr, // decrypt_context
+ backend_audio_buffer_.get());
+ EXPECT_NE(status, MediaPipelineBackend::kBufferFailed);
+ audio_buffers_.pop_front();
+
+ // Feeding is done, just wait for the end of stream callback.
+ if (buffer->end_of_stream() || audio_buffers_.empty()) {
+ if (audio_buffers_.empty() && !buffer->end_of_stream()) {
+ LOG(WARNING) << "Stream emptied without feeding EOS frame";
+ }
+
+ audio_feeding_completed_ = true;
+ return;
+ }
+
+ if (status == MediaPipelineBackend::kBufferPending)
+ return;
+
+ OnPushBufferComplete(audio_decoder_, MediaPipelineBackend::kBufferSuccess);
+}
+
+void AudioVideoPipelineDeviceTest::FeedVideoBuffer() {
+ // Possibly feed one frame
+ DCHECK(!video_buffers_.empty());
+ if (video_feeding_completed_)
+ return;
+
+ scoped_refptr<DecoderBufferBase> buffer = video_buffers_.front();
+ if (backend_video_buffer_)
+ backend_video_buffer_->set_buffer(buffer);
+ else
+ backend_video_buffer_.reset(new CastDecoderBufferImpl(buffer));
halliwell 2015/10/14 15:02:37 ditto
kmackay 2015/10/14 21:27:26 Done.
+
+ MediaPipelineBackend::BufferStatus status =
+ video_decoder_->PushBuffer(nullptr, // decrypt_context
+ backend_video_buffer_.get());
+ EXPECT_NE(status, MediaPipelineBackend::kBufferFailed);
+ video_buffers_.pop_front();
+
+ // Feeding is done, just wait for the end of stream callback.
+ if (buffer->end_of_stream() || video_buffers_.empty()) {
+ if (video_buffers_.empty() && !buffer->end_of_stream()) {
+ LOG(WARNING) << "Stream emptied without feeding EOS frame";
+ }
+
+ video_feeding_completed_ = true;
+ return;
+ }
- frames.push_back(
- scoped_refptr<DecoderBufferBase>(new DecoderBufferAdapter(
- ::media::DecoderBuffer::CreateEOSBuffer())));
+ if (status == MediaPipelineBackend::kBufferPending)
+ return;
- MediaComponentDeviceFeederForTest* device_feeder =
- new MediaComponentDeviceFeederForTest(video_pipeline_device, frames);
- device_feeder->Initialize(base::Bind(&AudioVideoPipelineDeviceTest::OnEos,
- base::Unretained(this),
- device_feeder));
- component_device_feeders_.push_back(device_feeder);
+ OnPushBufferComplete(video_decoder_, MediaPipelineBackend::kBufferSuccess);
}
void AudioVideoPipelineDeviceTest::Start() {
pause_time_ = base::TimeDelta();
pause_pattern_idx_ = 0;
- for (size_t i = 0; i < component_device_feeders_.size(); i++) {
+ if (audio_decoder_) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&AudioVideoPipelineDeviceTest::FeedAudioBuffer,
+ base::Unretained(this)));
+ }
+ if (video_decoder_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&MediaComponentDeviceFeederForTest::Feed,
- base::Unretained(component_device_feeders_[i])));
+ FROM_HERE,
+ base::Bind(&AudioVideoPipelineDeviceTest::FeedVideoBuffer,
+ base::Unretained(this)));
}
- media_clock_device_->SetState(MediaClockDevice::kStateRunning);
+ backend_->Start(0);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(&AudioVideoPipelineDeviceTest::MonitorLoop,
base::Unretained(this)));
}
+void AudioVideoPipelineDeviceTest::OnEndOfStream(
+ MediaPipelineBackend::Decoder* decoder) {
+ bool success = backend_->Stop();
+ ASSERT_TRUE(success);
+
+ if (decoder == audio_decoder_)
+ audio_decoder_ = nullptr;
+ else if (decoder == video_decoder_)
+ video_decoder_ = nullptr;
+
+ if (!audio_decoder_ && !video_decoder_)
+ base::MessageLoop::current()->QuitWhenIdle();
+}
+
+void AudioVideoPipelineDeviceTest::OnDecoderError(
+ MediaPipelineBackend::Decoder* decoder) {
+ ASSERT_TRUE(false);
+}
+
+void AudioVideoPipelineDeviceTest::OnPushBufferComplete(
+ MediaPipelineBackend::Decoder* decoder,
+ MediaPipelineBackend::BufferStatus status) {
+ EXPECT_NE(status, MediaPipelineBackend::kBufferFailed);
+
+ if (decoder == audio_decoder_) {
+ if (audio_feeding_completed_)
+ return;
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&AudioVideoPipelineDeviceTest::FeedAudioBuffer,
+ base::Unretained(this)));
+ } else if (decoder == video_decoder_) {
+ if (video_feeding_completed_)
+ return;
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&AudioVideoPipelineDeviceTest::FeedVideoBuffer,
+ base::Unretained(this)));
+ }
+}
+
void AudioVideoPipelineDeviceTest::MonitorLoop() {
- base::TimeDelta media_time = base::TimeDelta::FromMicroseconds(
- media_clock_device_->GetTimeMicroseconds());
+ base::TimeDelta media_time =
+ base::TimeDelta::FromMicroseconds(backend_->GetCurrentPts());
if (!pause_pattern_.empty() &&
pause_pattern_[pause_pattern_idx_].delay >= base::TimeDelta() &&
media_time >= pause_time_ + pause_pattern_[pause_pattern_idx_].delay) {
// Do Pause
- media_clock_device_->SetRate(0.0);
- pause_time_ = base::TimeDelta::FromMicroseconds(
- media_clock_device_->GetTimeMicroseconds());
+ backend_->Pause();
+ pause_time_ = base::TimeDelta::FromMicroseconds(backend_->GetCurrentPts());
VLOG(2) << "Pausing at " << pause_time_.InMilliseconds() << "ms for " <<
pause_pattern_[pause_pattern_idx_].length.InMilliseconds() << "ms";
@@ -285,8 +405,8 @@ void AudioVideoPipelineDeviceTest::MonitorLoop() {
void AudioVideoPipelineDeviceTest::OnPauseCompleted() {
// Make sure the media time didn't move during that time.
- base::TimeDelta media_time = base::TimeDelta::FromMicroseconds(
- media_clock_device_->GetTimeMicroseconds());
+ base::TimeDelta media_time =
+ base::TimeDelta::FromMicroseconds(backend_->GetCurrentPts());
// TODO(damienv):
// Should be:
@@ -303,41 +423,16 @@ void AudioVideoPipelineDeviceTest::OnPauseCompleted() {
VLOG(2) << "Pause complete, restarting media clock";
// Resume playback and frame feeding.
- media_clock_device_->SetRate(1.0);
+ backend_->Resume();
MonitorLoop();
}
-void AudioVideoPipelineDeviceTest::OnEos(
- MediaComponentDeviceFeederForTest* device_feeder) {
- for (ComponentDeviceIterator it = component_device_feeders_.begin();
- it != component_device_feeders_.end();
- ++it) {
- if (*it == device_feeder) {
- component_device_feeders_.erase(it);
- break;
- }
- }
-
- // Check if all streams finished
- if (component_device_feeders_.empty())
- base::MessageLoop::current()->QuitWhenIdle();
-}
-
void AudioVideoPipelineDeviceTest::Initialize() {
// Create the media device.
task_runner_.reset(new TaskRunnerImpl());
MediaPipelineDeviceParams params(task_runner_.get());
backend_.reset(CastMediaShlib::CreateMediaPipelineBackend(params));
- media_clock_device_ = backend_->GetClock();
-
- // Clock initialization and configuration.
- bool success =
- media_clock_device_->SetState(MediaClockDevice::kStateIdle);
- ASSERT_TRUE(success);
- success = media_clock_device_->ResetTimeline(0);
- ASSERT_TRUE(success);
- media_clock_device_->SetRate(1.0);
}
TEST_F(AudioVideoPipelineDeviceTest, Mp3Playback) {

Powered by Google App Engine
This is Rietveld 408576698