blob: 1aef0964d2f91f0af8afa77ee15083f64ec69885 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fcntl.h>
#include <fuchsia/media/playback/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/sys/cpp/testing/test_with_environment.h>
#include <queue>
#include "lib/media/cpp/timeline_function.h"
#include "lib/media/cpp/type_converters.h"
#include "lib/ui/scenic/cpp/view_token_pair.h"
#include "src/lib/fsl/io/fd.h"
#include "src/lib/syslog/cpp/logger.h"
#include "src/media/playback/mediaplayer/test/command_queue.h"
#include "src/media/playback/mediaplayer/test/fakes/fake_audio.h"
#include "src/media/playback/mediaplayer/test/fakes/fake_scenic.h"
#include "src/media/playback/mediaplayer/test/fakes/fake_wav_reader.h"
#include "src/media/playback/mediaplayer/test/sink_feeder.h"
namespace media_player {
namespace test {
static constexpr uint16_t kSamplesPerFrame = 2; // Stereo
static constexpr uint32_t kFramesPerSecond = 48000; // 48kHz
static constexpr size_t kSinkFeedSize = 65536;
static constexpr uint32_t kSinkFeedMaxPacketSize = 4096;
static constexpr uint32_t kSinkFeedMaxPacketCount = 10;
constexpr char kBearFilePath[] = "/pkg/data/media_test_data/bear.mp4";
constexpr char kOpusFilePath[] = "/pkg/data/media_test_data/sfx-opus-441.webm";
// Base class for mediaplayer tests.
class MediaPlayerTests : public sys::testing::TestWithEnvironment {
protected:
void SetUp() override {
auto services = CreateServices();
// Add the service under test using its launch info.
fuchsia::sys::LaunchInfo launch_info{
"fuchsia-pkg://fuchsia.com/mediaplayer#meta/mediaplayer.cmx"};
zx_status_t status = services->AddServiceWithLaunchInfo(
std::move(launch_info), fuchsia::media::playback::Player::Name_);
EXPECT_EQ(ZX_OK, status);
services->AddService(fake_audio_.GetRequestHandler());
services->AddService(fake_scenic_.GetRequestHandler());
// Create the synthetic environment.
environment_ = CreateNewEnclosingEnvironment("mediaplayer_tests", std::move(services));
// Instantiate the player under test.
environment_->ConnectToService(player_.NewRequest());
commands_.Init(player_.get());
player_.set_error_handler([this](zx_status_t status) {
FX_LOGS(ERROR) << "Player connection closed, status " << status << ".";
player_connection_closed_ = true;
QuitLoop();
});
player_.events().OnStatusChanged = [this](fuchsia::media::playback::PlayerStatus status) {
commands_.NotifyStatusChanged(status);
};
}
void TearDown() override { EXPECT_FALSE(player_connection_closed_); }
// Queues commands to wait for end of stream and to call |QuitLoop|.
void QuitOnEndOfStream() {
commands_.WaitForEndOfStream();
commands_.Invoke([this]() { QuitLoop(); });
}
// Executes queued commands
void Execute() {
commands_.Execute();
RunLoop();
}
// Creates a view.
void CreateView() {
auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
player_->CreateView(std::move(view_token));
view_holder_token_ = std::move(view_holder_token);
}
fuchsia::media::playback::PlayerPtr player_;
bool player_connection_closed_ = false;
FakeWavReader fake_reader_;
FakeAudio fake_audio_;
FakeScenic fake_scenic_;
fuchsia::ui::views::ViewHolderToken view_holder_token_;
std::unique_ptr<sys::testing::EnclosingEnvironment> environment_;
bool sink_connection_closed_ = false;
SinkFeeder sink_feeder_;
CommandQueue commands_;
};
// Play a synthetic WAV file from beginning to end.
TEST_F(MediaPlayerTests, PlayWav) {
fake_audio_.renderer().ExpectPackets({{0, 4096, 0x20c39d1e31991800},
{1024, 4096, 0xeaf137125d313800},
{2048, 4096, 0x6162095671991800},
{3072, 4096, 0x36e551c7dd41f800},
{4096, 4096, 0x23dcbf6fb1991800},
{5120, 4096, 0xee0a5963dd313800},
{6144, 4096, 0x647b2ba7f1991800},
{7168, 4096, 0x39fe74195d41f800},
{8192, 4096, 0xb3de76b931991800},
{9216, 4096, 0x7e0c10ad5d313800},
{10240, 4096, 0xf47ce2f171991800},
{11264, 4096, 0xca002b62dd41f800},
{12288, 4096, 0xb6f7990ab1991800},
{13312, 4096, 0x812532fedd313800},
{14336, 4096, 0xf7960542f1991800},
{15360, 4052, 0x7308a9824acbd5ea}});
fuchsia::media::playback::SeekingReaderPtr fake_reader_ptr;
fidl::InterfaceRequest<fuchsia::media::playback::SeekingReader> reader_request =
fake_reader_ptr.NewRequest();
fake_reader_.Bind(std::move(reader_request));
fuchsia::media::playback::SourcePtr source;
player_->CreateReaderSource(std::move(fake_reader_ptr), source.NewRequest());
player_->SetSource(std::move(source));
commands_.Play();
QuitOnEndOfStream();
Execute();
EXPECT_TRUE(fake_audio_.renderer().expected());
}
// Play a synthetic WAV file from beginning to end, delaying the retirement of
// the last packet to simulate delayed end-of-stream recognition.
// TODO(fxb/35616): Flaking.
TEST_F(MediaPlayerTests, DISABLED_PlayWavDelayEos) {
fake_audio_.renderer().ExpectPackets({{0, 4096, 0x20c39d1e31991800},
{1024, 4096, 0xeaf137125d313800},
{2048, 4096, 0x6162095671991800},
{3072, 4096, 0x36e551c7dd41f800},
{4096, 4096, 0x23dcbf6fb1991800},
{5120, 4096, 0xee0a5963dd313800},
{6144, 4096, 0x647b2ba7f1991800},
{7168, 4096, 0x39fe74195d41f800},
{8192, 4096, 0xb3de76b931991800},
{9216, 4096, 0x7e0c10ad5d313800},
{10240, 4096, 0xf47ce2f171991800},
{11264, 4096, 0xca002b62dd41f800},
{12288, 4096, 0xb6f7990ab1991800},
{13312, 4096, 0x812532fedd313800},
{14336, 4096, 0xf7960542f1991800},
{15360, 4052, 0x7308a9824acbd5ea}});
fuchsia::media::playback::SeekingReaderPtr fake_reader_ptr;
fidl::InterfaceRequest<fuchsia::media::playback::SeekingReader> reader_request =
fake_reader_ptr.NewRequest();
fake_reader_.Bind(std::move(reader_request));
fuchsia::media::playback::SourcePtr source;
player_->CreateReaderSource(std::move(fake_reader_ptr), source.NewRequest());
player_->SetSource(std::move(source));
fake_audio_.renderer().DelayPacketRetirement(15360);
commands_.Play();
QuitOnEndOfStream();
Execute();
EXPECT_TRUE(fake_audio_.renderer().expected());
}
// Play a synthetic WAV file from beginning to end, retaining packets. This
// tests the ability of the player to handle the case in which the audio
// renderer is holding on to packets for too long.
TEST_F(MediaPlayerTests, PlayWavRetainPackets) {
fake_audio_.renderer().SetRetainPackets(true);
fuchsia::media::playback::SeekingReaderPtr fake_reader_ptr;
fidl::InterfaceRequest<fuchsia::media::playback::SeekingReader> reader_request =
fake_reader_ptr.NewRequest();
fake_reader_.Bind(std::move(reader_request));
// Need more than 1s of data.
fake_reader_.SetSize(256000);
fuchsia::media::playback::SourcePtr source;
player_->CreateReaderSource(std::move(fake_reader_ptr), source.NewRequest());
player_->SetSource(std::move(source));
commands_.Play();
QuitOnEndOfStream();
Execute();
EXPECT_TRUE(fake_audio_.renderer().expected());
}
// Play an LPCM elementary stream using |ElementarySource|
TEST_F(MediaPlayerTests, ElementarySource) {
fake_audio_.renderer().ExpectPackets({{0, 4096, 0xd2fbd957e3bf0000},
{1024, 4096, 0xda25db3fa3bf0000},
{2048, 4096, 0xe227e0f6e3bf0000},
{3072, 4096, 0xe951e2dea3bf0000},
{4096, 4096, 0x37ebf7d3e3bf0000},
{5120, 4096, 0x3f15f9bba3bf0000},
{6144, 4096, 0x4717ff72e3bf0000},
{7168, 4096, 0x4e42015aa3bf0000},
{8192, 4096, 0xeabc5347e3bf0000},
{9216, 4096, 0xf1e6552fa3bf0000},
{10240, 4096, 0xf9e85ae6e3bf0000},
{11264, 4096, 0x01125ccea3bf0000},
{12288, 4096, 0x4fac71c3e3bf0000},
{13312, 4096, 0x56d673aba3bf0000},
{14336, 4096, 0x5ed87962e3bf0000},
{15360, 4096, 0x66027b4aa3bf0000}});
fuchsia::media::playback::ElementarySourcePtr elementary_source;
player_->CreateElementarySource(0, false, false, nullptr, elementary_source.NewRequest());
fuchsia::media::AudioStreamType audio_stream_type;
audio_stream_type.sample_format = fuchsia::media::AudioSampleFormat::SIGNED_16;
audio_stream_type.channels = kSamplesPerFrame;
audio_stream_type.frames_per_second = kFramesPerSecond;
fuchsia::media::StreamType stream_type;
stream_type.medium_specific.set_audio(std::move(audio_stream_type));
stream_type.encoding = fuchsia::media::AUDIO_ENCODING_LPCM;
fuchsia::media::SimpleStreamSinkPtr sink;
elementary_source->AddStream(std::move(stream_type), kFramesPerSecond, 1, sink.NewRequest());
sink.set_error_handler([this](zx_status_t status) {
FX_LOGS(ERROR) << "SimpleStreamSink connection closed.";
sink_connection_closed_ = true;
QuitLoop();
});
// Here we're upcasting from a
// |fidl::InterfaceHandle<fuchsia::media::playback::ElementarySource>| to a
// |fidl::InterfaceHandle<fuchsia::media::playback::Source>| the only way we
// currently can. The compiler has no way of knowing whether this is
// legit.
// TODO(dalesat): Do this safely once FIDL-329 is fixed.
player_->SetSource(fidl::InterfaceHandle<fuchsia::media::playback::Source>(
elementary_source.Unbind().TakeChannel()));
sink_feeder_.Init(std::move(sink), kSinkFeedSize, kSamplesPerFrame * sizeof(int16_t),
kSinkFeedMaxPacketSize, kSinkFeedMaxPacketCount);
commands_.Play();
QuitOnEndOfStream();
Execute();
EXPECT_TRUE(fake_audio_.renderer().expected());
EXPECT_FALSE(sink_connection_closed_);
}
// Opens an SBC elementary stream using |ElementarySource|.
TEST_F(MediaPlayerTests, ElementarySourceWithSBC) {
fuchsia::media::playback::ElementarySourcePtr elementary_source;
player_->CreateElementarySource(1, false, false, nullptr, elementary_source.NewRequest());
fuchsia::media::AudioStreamType audio_stream_type;
audio_stream_type.sample_format = fuchsia::media::AudioSampleFormat::SIGNED_16;
audio_stream_type.channels = kSamplesPerFrame;
audio_stream_type.frames_per_second = kFramesPerSecond;
fuchsia::media::StreamType stream_type;
stream_type.medium_specific.set_audio(std::move(audio_stream_type));
stream_type.encoding = fuchsia::media::AUDIO_ENCODING_SBC;
fuchsia::media::SimpleStreamSinkPtr sink;
elementary_source->AddStream(std::move(stream_type), kFramesPerSecond, 1, sink.NewRequest());
sink.set_error_handler([this](zx_status_t status) {
FX_LOGS(ERROR) << "SimpleStreamSink connection closed.";
sink_connection_closed_ = true;
QuitLoop();
});
// Here we're upcasting from a
// |fidl::InterfaceHandle<fuchsia::media::playback::ElementarySource>| to a
// |fidl::InterfaceHandle<fuchsia::media::playback::Source>| the only way we
// currently can. The compiler has no way of knowing whether this is
// legit.
// TODO(FIDL-329): Do this safely once FIDL-329 is fixed.
player_->SetSource(fidl::InterfaceHandle<fuchsia::media::playback::Source>(
elementary_source.Unbind().TakeChannel()));
commands_.WaitForAudioConnected();
commands_.Invoke([this]() { QuitLoop(); });
Execute();
EXPECT_FALSE(sink_connection_closed_);
}
// Opens an AAC elementary stream using |ElementarySource|.
TEST_F(MediaPlayerTests, ElementarySourceWithAAC) {
fuchsia::media::playback::ElementarySourcePtr elementary_source;
player_->CreateElementarySource(1, false, false, nullptr, elementary_source.NewRequest());
fuchsia::media::AudioStreamType audio_stream_type;
audio_stream_type.sample_format = fuchsia::media::AudioSampleFormat::SIGNED_16;
audio_stream_type.channels = kSamplesPerFrame;
audio_stream_type.frames_per_second = kFramesPerSecond;
fuchsia::media::StreamType stream_type;
stream_type.medium_specific.set_audio(std::move(audio_stream_type));
stream_type.encoding = fuchsia::media::AUDIO_ENCODING_AAC;
fuchsia::media::SimpleStreamSinkPtr sink;
elementary_source->AddStream(std::move(stream_type), kFramesPerSecond, 1, sink.NewRequest());
sink.set_error_handler([this](zx_status_t status) {
FX_LOGS(ERROR) << "SimpleStreamSink connection closed.";
sink_connection_closed_ = true;
QuitLoop();
});
// Here we're upcasting from a
// |fidl::InterfaceHandle<fuchsia::media::playback::ElementarySource>| to a
// |fidl::InterfaceHandle<fuchsia::media::playback::Source>| the only way we
// currently can. The compiler has no way of knowing whether this is
// legit.
// TODO(FIDL-329): Do this safely once FIDL-329 is fixed.
player_->SetSource(fidl::InterfaceHandle<fuchsia::media::playback::Source>(
elementary_source.Unbind().TakeChannel()));
commands_.WaitForAudioConnected();
commands_.Invoke([this]() { QuitLoop(); });
Execute();
EXPECT_FALSE(sink_connection_closed_);
}
// Opens an AACLATM elementary stream using |ElementarySource|.
TEST_F(MediaPlayerTests, ElementarySourceWithAACLATM) {
fuchsia::media::playback::ElementarySourcePtr elementary_source;
player_->CreateElementarySource(1, false, false, nullptr, elementary_source.NewRequest());
fuchsia::media::AudioStreamType audio_stream_type;
audio_stream_type.sample_format = fuchsia::media::AudioSampleFormat::SIGNED_16;
audio_stream_type.channels = kSamplesPerFrame;
audio_stream_type.frames_per_second = kFramesPerSecond;
fuchsia::media::StreamType stream_type;
stream_type.medium_specific.set_audio(std::move(audio_stream_type));
stream_type.encoding = fuchsia::media::AUDIO_ENCODING_AACLATM;
fuchsia::media::SimpleStreamSinkPtr sink;
elementary_source->AddStream(std::move(stream_type), kFramesPerSecond, 1, sink.NewRequest());
sink.set_error_handler([this](zx_status_t status) {
FX_LOGS(ERROR) << "SimpleStreamSink connection closed.";
sink_connection_closed_ = true;
QuitLoop();
});
// Here we're upcasting from a
// |fidl::InterfaceHandle<fuchsia::media::playback::ElementarySource>| to a
// |fidl::InterfaceHandle<fuchsia::media::playback::Source>| the only way we
// currently can. The compiler has no way of knowing whether this is
// legit.
// TODO(FIDL-329): Do this safely once FIDL-329 is fixed.
player_->SetSource(fidl::InterfaceHandle<fuchsia::media::playback::Source>(
elementary_source.Unbind().TakeChannel()));
commands_.WaitForAudioConnected();
commands_.Invoke([this]() { QuitLoop(); });
Execute();
EXPECT_FALSE(sink_connection_closed_);
}
// Tries to open a bogus elementary stream using |ElementarySource|.
TEST_F(MediaPlayerTests, ElementarySourceWithBogus) {
fuchsia::media::playback::ElementarySourcePtr elementary_source;
player_->CreateElementarySource(1, false, false, nullptr, elementary_source.NewRequest());
fuchsia::media::AudioStreamType audio_stream_type;
audio_stream_type.sample_format = fuchsia::media::AudioSampleFormat::SIGNED_16;
audio_stream_type.channels = kSamplesPerFrame;
audio_stream_type.frames_per_second = kFramesPerSecond;
fuchsia::media::StreamType stream_type;
stream_type.medium_specific.set_audio(std::move(audio_stream_type));
stream_type.encoding = "bogus encoding";
fuchsia::media::SimpleStreamSinkPtr sink;
elementary_source->AddStream(std::move(stream_type), kFramesPerSecond, 1, sink.NewRequest());
sink.set_error_handler([this](zx_status_t status) {
FX_LOGS(ERROR) << "SimpleStreamSink connection closed.";
sink_connection_closed_ = true;
QuitLoop();
});
// Here we're upcasting from a
// |fidl::InterfaceHandle<fuchsia::media::playback::ElementarySource>| to a
// |fidl::InterfaceHandle<fuchsia::media::playback::Source>| the only way we
// currently can. The compiler has no way of knowing whether this is
// legit.
// TODO(FIDL-329): Do this safely once is fixed.
player_->SetSource(fidl::InterfaceHandle<fuchsia::media::playback::Source>(
elementary_source.Unbind().TakeChannel()));
commands_.WaitForProblem();
commands_.Invoke([this]() { QuitLoop(); });
Execute();
EXPECT_FALSE(sink_connection_closed_);
}
// Play a real A/V file from beginning to end.
TEST_F(MediaPlayerTests, PlayBear) {
// Previously, we were getting different audio packets for arm64 vs x64. This doesn't appear
// to be happening anymore, but in case it recurs, we dump packets here. The output can be used
// to create a second list of packets to expect.
fake_audio_.renderer().DumpPackets();
fake_audio_.renderer().ExpectPackets(
{{1024, 8192, 0x0a68b3995a50a648}, {2048, 8192, 0x93bf522ee77e9d50},
{3072, 8192, 0x89cc3bcedd6034be}, {4096, 8192, 0x40931af9f379dd00},
{5120, 8192, 0x79dc4cfe61738988}, {6144, 8192, 0x2c831d823db62908},
{7168, 8192, 0x71561155059a2950}, {8192, 8192, 0x4581449f2e040ff0},
{9216, 8192, 0xb0429eeed8b7424e}, {10240, 8192, 0x5e7007ebe169fcc0},
{11264, 8192, 0x585fe50f30788fd8}, {12288, 8192, 0x7cba92a4ecaf59a2},
{13312, 8192, 0x8521ccbccc4d771e}, {14336, 8192, 0x5694e56b0fd93cc8},
{15360, 8192, 0x14abced62917c788}, {16384, 8192, 0x8e7f3918fa412a02},
{17408, 8192, 0xf095ec04d2238644}, {18432, 8192, 0x886cab3f4e3f9610},
{19456, 8192, 0x874a3d8d0f4e2190}, {20480, 8192, 0x1f70d5763dadf9ac},
{21504, 8192, 0x2619ff3221cbab46}, {22528, 8192, 0x33aa3594808f6b10},
{23552, 8192, 0x2da9b93cacd110a4}, {24576, 8192, 0x2f0def95d105b68c},
{25600, 8192, 0xef9acc73b96291c4}, {26624, 8192, 0xca8ed12c8f4b7b06},
{27648, 8192, 0x0ea5eddd4cc5e3bc}, {28672, 8192, 0xafe4007e4779438e},
{29696, 8192, 0xcefebc7fe3257f9e}, {30720, 8192, 0x4294978d0dc213ee},
{31744, 8192, 0x53ca41b8a5175774}, {32768, 8192, 0x9a16b082e9e5a95e},
{33792, 8192, 0x1a849b5e1f4ee80a}, {34816, 8192, 0xd1741d4e44972fea},
{35840, 8192, 0x7ecf5a82a4adf9a6}, {36864, 8192, 0x2878988793205f22},
{37888, 8192, 0x35a41b25f24ec2b8}, {38912, 8192, 0x2714de582b48ebc6},
{39936, 8192, 0xc8fdea128f0285f4}, {40960, 8192, 0xc5ab19b2405542ca},
{41984, 8192, 0x5d5d781722ba0392}, {43008, 8192, 0x02fe263969ba81a6},
{44032, 8192, 0x1acc5b7c24d197d4}, {45056, 8192, 0x18d713e058acfec8},
{46080, 8192, 0x83573b4a6f02c8da}, {47104, 8192, 0xacffcaaff833e850},
{48128, 8192, 0xa0cffe3e485c46c4}, {49152, 8192, 0xffd5680f78b7f7a2},
{50176, 8192, 0xc950e93a5272cda8}, {51200, 8192, 0x375e4dc1dc28eea4},
{52224, 8192, 0x5648dd0ed9d9d9d4}, {53248, 8192, 0xac945623bf04f5b6},
{54272, 8192, 0x3cff2936986fcdc8}, {55296, 8192, 0xbc049d18bdcca182},
{56320, 8192, 0x8d3646f2e29da29c}, {57344, 8192, 0xb5e72da09cd9f5b4},
{58368, 8192, 0x8597406852caa548}, {59392, 8192, 0x5221d69a113d9688},
{60416, 8192, 0xc4c0bdef8e07fb12}, {61440, 8192, 0x804e43c36110196e},
{62464, 8192, 0xd1d3ae38126dd618}, {63488, 8192, 0x846d01cfa3be6500},
{64512, 8192, 0xecca760a67eff43a}, {65536, 8192, 0x6624720182df5730},
{66560, 8192, 0x41eb3d61d94b2224}, {67584, 8192, 0x015efd07043b4e4c},
{68608, 8192, 0x2d4d9823e0e63b64}, {69632, 8192, 0xd5a845cbf966e23a},
{70656, 8192, 0x24c6ccf454693f72}, {71680, 8192, 0x368bea38398d5ecc},
{72704, 8192, 0x3602a6b0602a9458}, {73728, 8192, 0x48ea44911825e784},
{74752, 8192, 0x53e549d74eb26de0}, {75776, 8192, 0x3f7f7f5c7ee3d14e},
{76800, 8192, 0xdcafb6baa55625f6}, {77824, 8192, 0x472b007f3bc3c45c},
{78848, 8192, 0x53a8ecc580fff982}, {79872, 8192, 0xf59a57769900ca62},
{80896, 8192, 0xcc380147f73a1528}, {81920, 8192, 0x4f4b79f5ad21e67e},
{82944, 8192, 0xcee2192004c8066c}, {83968, 8192, 0x84672c98f8a1da4c},
{84992, 8192, 0x229246edd7b6c31c}, {86016, 8192, 0x3f3f4d7f8fcd62b4},
{87040, 8192, 0x46bc2a4e9e6d40ca}, {88064, 8192, 0xa6901df8e4afcc48},
{89088, 8192, 0x8e96017b64980fd8}, {90112, 8192, 0xdd9001f337c6a932},
{91136, 8192, 0xac5913cdd15b8a72}, {92160, 8192, 0xd9d59a367d561d4c},
{93184, 8192, 0xa76421aaa4b469c8}, {94208, 8192, 0x2e27a33a898c0056},
{95232, 8192, 0xb71592d727280bc0}, {96256, 8192, 0xb73b2e5a682cbf60},
{97280, 8192, 0x36d9f03861277c10}, {98304, 8192, 0xffa1d33f4aea2e40},
{99328, 8192, 0x4359627a59f6552e}, {100352, 8192, 0x82a76e3c810aee68},
{101376, 8192, 0x60066a5773c5dee2}, {102400, 8192, 0x809989d272e85654},
{103424, 8192, 0xd1cdd52e37d58702}, {104448, 8192, 0xe332d1115653f36c},
{105472, 8192, 0xa1189ac1a76c3bd0}, {106496, 8192, 0xaa20304ceb8e6daa},
{107520, 8192, 0x913ac8dcdc5cef52}, {108544, 8192, 0x891883b9326cd0f4},
{109568, 8192, 0xe8fbce45cf3990a4}, {110592, 8192, 0xc9301a9ef899455c},
{111616, 8192, 0x56cd5306b56e027a}, {112640, 8192, 0x5a1b088bce12b0f8},
{113664, 8192, 0xc697191375e99274}, {114688, 8192, 0x4d0f0798a59771c4},
{115712, 8192, 0x6571a4ff90e63490}, {116736, 8192, 0x20ffb62fff517f00},
{117760, 8192, 0x20ffb62fff517f00}, {118784, 8192, 0x20ffb62fff517f00},
{119808, 8192, 0x20ffb62fff517f00}, {120832, 8192, 0x20ffb62fff517f00}});
fake_scenic_.session().SetExpectations(
1,
{
.width = 2,
.height = 2,
.stride = 2 * sizeof(uint32_t),
.pixel_format = fuchsia::images::PixelFormat::BGRA_8,
},
{
.width = 1280,
.height = 738,
.stride = 1280,
.pixel_format = fuchsia::images::PixelFormat::YV12,
},
720, {{0, 944640, 0x0864378c3655ba47}, {133729451, 944640, 0x2481a21b1e543c8e},
{167096118, 944640, 0xe4294049f22539bc}, {200462784, 944640, 0xde1058aba916ffad},
{233829451, 944640, 0xc3fc580b34dc0383}, {267196118, 944640, 0xff31322e5ccdebe0},
{300562784, 944640, 0x64d31206ece7417f}, {333929451, 944640, 0xf1c6bf7fe1be29be},
{367296118, 944640, 0x72f44e5249a05c15}, {400662784, 944640, 0x1ad7e92183fb3aa4},
{434029451, 944640, 0x24b78b95d8c8b73d}, {467396118, 944640, 0x25a798d9af5a1b7e},
{500762784, 944640, 0x3379288b1f4197a5}, {534129451, 944640, 0x15fb9c205590cbc9},
{567496118, 944640, 0xc04a1834aec8b399}, {600862784, 944640, 0x97eded0e3b6348d3},
{634229451, 944640, 0x09dba227982ba479}, {667596118, 944640, 0x4d2a1042babc479c},
{700962784, 944640, 0x379f96a35774dc2b}, {734329451, 944640, 0x2d95a4b5506bd4c3},
{767696118, 944640, 0xda99bf00cd971999}, {801062784, 944640, 0x20a21550eb717da2},
{834429451, 944640, 0x3733b96d2279460b}, {867796118, 944640, 0x8ea51ee0088cda67},
{901162784, 944640, 0x8d6af19e5d9629ae}, {934529451, 944640, 0xd9765bd28098f093},
{967896118, 944640, 0x9a747455b496c9d1}, {1001262784, 944640, 0xfc8e90e73cc086f6},
{1034629451, 944640, 0xc3dec92946fc0005}, {1067996118, 944640, 0x215b196e790214c4},
{1101362784, 944640, 0x30b114015d719041}, {1134729451, 944640, 0x5ed6e582ac4022a1},
{1168096118, 944640, 0xbccb6f8ba8601507}, {1201462784, 944640, 0x34eab6666dc6c717},
{1234829451, 944640, 0x5e33bfc44650245f}, {1268196118, 944640, 0x736397b78e0850ff},
{1301562784, 944640, 0x620d7190a9e49a31}, {1334929451, 944640, 0x436e952327e311ea},
{1368296118, 944640, 0xf6fa16fc170a85f3}, {1401662784, 944640, 0x9f457e1a66323ead},
{1435029451, 944640, 0xb1747e31ea5358db}, {1468396118, 944640, 0x4da84ec1c5cb45de},
{1501762784, 944640, 0x5454f9007dc4de01}, {1535129451, 944640, 0x8e9777accf38e4f0},
{1568496118, 944640, 0x16a2ebade809e497}, {1601862784, 944640, 0x36d323606ebca2f4},
{1635229451, 944640, 0x17eaf1e84353dec9}, {1668596118, 944640, 0xdb1b344498520386},
{1701962784, 944640, 0xec53764065860e7f}, {1735329451, 944640, 0x110a7dddd4c45a54},
{1768696118, 944640, 0x6df1c973722f01c7}, {1802062784, 944640, 0x2e18f1e1544e002a},
{1835429451, 944640, 0x0de7b784dd8b0494}, {1868796118, 944640, 0x6e254cd1652be6a9},
{1902162784, 944640, 0x6353cb7c270b06c2}, {1935529451, 944640, 0x8d62a2ddb0350ab9},
{1968896118, 944640, 0xaf0ee1376ded95cd}, {2002262784, 944640, 0xf617917814de4169},
{2035629451, 944640, 0xf686efcec861909f}, {2068996118, 944640, 0x539f93afe6863cca},
{2102362784, 944640, 0x12c5c5e4eb5b2649}, {2135729451, 944640, 0x984cf8179effd823},
{2169096118, 944640, 0xfcb0cc2eb449ed16}, {2202462784, 944640, 0xf070b3572db477cc},
{2235829451, 944640, 0x5dd53f712ce8e1a6}, {2269196118, 944640, 0x02e0600528534bef},
{2302562784, 944640, 0x53120fbaca19e13b}, {2335929451, 944640, 0xd66e3cb3e70897eb},
{2369296118, 944640, 0x9f4138aa8e84cbf4}, {2402662784, 944640, 0xf350694d6a12ec39},
{2436029451, 944640, 0x08c986a97ab8fbb3}, {2469396118, 944640, 0x229d2b908659b728},
{2502762784, 944640, 0xf54cbe4582a3f8e1}, {2536129451, 944640, 0x8c8985c6649a3e1c},
{2569496118, 944640, 0x711e04eccc5e4527}, {2602862784, 944640, 0x78e2979034921e70},
{2636229451, 944640, 0x51c3524f5bf83a62}, {2669596118, 944640, 0x12b6f7b7591e7044},
{2702962784, 944640, 0xca8d7ac09b973a4b}, {2736329451, 944640, 0x3e666b376fcaa466},
{2769696118, 944640, 0x8f3657c9648b6dbb}, {2803062784, 944640, 0x19a30916a3375f4e}});
CreateView();
commands_.SetFile(kBearFilePath);
commands_.Play();
QuitOnEndOfStream();
Execute();
EXPECT_TRUE(fake_audio_.renderer().expected());
EXPECT_TRUE(fake_scenic_.session().expected());
}
// Play an opus file from beginning to end.
TEST_F(MediaPlayerTests, PlayOpus) {
// The decoder works a bit differently on x64 vs arm64, hence the two lists here.
fake_audio_.renderer().ExpectPackets({{-336, 1296, 0x47ff30edd64831d6},
{312, 1920, 0xcc4016bbb348e52b},
{1272, 1920, 0xe54a89514c636028},
{2232, 1920, 0x8ef31ce86009d7da},
{3192, 1920, 0x36490fe70ca3bb81},
{4152, 1920, 0x4a8bdd8e9c2f42bb},
{5112, 1920, 0xbc8cea1839f0299e},
{6072, 1920, 0x868a68451d7ab814},
{7032, 1920, 0x84ac9b11a685a9a9},
{7992, 1920, 0xe4359c110afe8adb},
{8952, 1920, 0x2092c7fbf2ff0f0c},
{9912, 1920, 0x8002d77665736d63},
{10872, 1920, 0x541b415fbdc7b268},
{11832, 1920, 0xe81ef757a5953573},
{12792, 1920, 0xbc70aba0ed44f7dc}});
fake_audio_.renderer().ExpectPackets({{-336, 1296, 0xbf1f56243e245a2c},
{312, 1920, 0x670e69ee3076c4b2},
{1272, 1920, 0xe0667e312e65207d},
{2232, 1920, 0x291ffa6baf5dd2b1},
{3192, 1920, 0x1b408d840e27bcc1},
{4152, 1920, 0xdbf5034a75bc761b},
{5112, 1920, 0x46fa968eb705415b},
{7032, 1920, 0x7256d4c58d7afe56},
{7992, 1920, 0xb2a7bc50ce80c898},
{8952, 1920, 0xb314415fd9c3a694},
{9912, 1920, 0x34d9ce067ffacc37},
{11832, 1920, 0x05fd64442f53c5cc},
{12792, 1920, 0x3e2a98426c8680d0}});
commands_.SetFile(kOpusFilePath);
commands_.Play();
QuitOnEndOfStream();
Execute();
EXPECT_TRUE(fake_audio_.renderer().expected());
}
// Play a real A/V file from beginning to end, retaining audio packets. This
// tests the ability of the player to handle the case in which the audio
// renderer is holding on to packets for too long.
TEST_F(MediaPlayerTests, PlayBearRetainAudioPackets) {
CreateView();
fake_audio_.renderer().SetRetainPackets(true);
commands_.SetFile(kBearFilePath);
commands_.Play();
QuitOnEndOfStream();
Execute();
EXPECT_TRUE(fake_audio_.renderer().expected());
EXPECT_TRUE(fake_scenic_.session().expected());
}
// Regression test for US-544.
TEST_F(MediaPlayerTests, RegressionTestUS544) {
CreateView();
commands_.SetFile(kBearFilePath);
// Play for two seconds and pause.
commands_.Play();
commands_.WaitForPosition(zx::sec(2));
commands_.Pause();
// Wait a bit.
commands_.Sleep(zx::sec(2));
// Seek to the beginning and resume playing.
commands_.Seek(zx::sec(0));
commands_.Play();
QuitOnEndOfStream();
Execute();
EXPECT_TRUE(fake_audio_.renderer().expected());
EXPECT_TRUE(fake_scenic_.session().expected());
}
// Regression test for QA-539.
// Verifies that the player can play two files in a row.
TEST_F(MediaPlayerTests, RegressionTestQA539) {
CreateView();
commands_.SetFile(kBearFilePath);
// Play the file to the end.
commands_.Play();
commands_.WaitForEndOfStream();
// Reload the file.
commands_.SetFile(kBearFilePath);
commands_.Play();
QuitOnEndOfStream();
Execute();
EXPECT_TRUE(fake_audio_.renderer().expected());
EXPECT_TRUE(fake_scenic_.session().expected());
}
// Play an LPCM elementary stream using |ElementarySource|. We delay calling SetSource to ensure
// that the SimpleStreamSink defers taking any action until it's properly connected.
TEST_F(MediaPlayerTests, ElementarySourceDeferred) {
fake_audio_.renderer().ExpectPackets({{0, 4096, 0xd2fbd957e3bf0000},
{1024, 4096, 0xda25db3fa3bf0000},
{2048, 4096, 0xe227e0f6e3bf0000},
{3072, 4096, 0xe951e2dea3bf0000},
{4096, 4096, 0x37ebf7d3e3bf0000},
{5120, 4096, 0x3f15f9bba3bf0000},
{6144, 4096, 0x4717ff72e3bf0000},
{7168, 4096, 0x4e42015aa3bf0000},
{8192, 4096, 0xeabc5347e3bf0000},
{9216, 4096, 0xf1e6552fa3bf0000},
{10240, 4096, 0xf9e85ae6e3bf0000},
{11264, 4096, 0x01125ccea3bf0000},
{12288, 4096, 0x4fac71c3e3bf0000},
{13312, 4096, 0x56d673aba3bf0000},
{14336, 4096, 0x5ed87962e3bf0000},
{15360, 4096, 0x66027b4aa3bf0000}});
fuchsia::media::playback::ElementarySourcePtr elementary_source;
player_->CreateElementarySource(0, false, false, nullptr, elementary_source.NewRequest());
fuchsia::media::AudioStreamType audio_stream_type;
audio_stream_type.sample_format = fuchsia::media::AudioSampleFormat::SIGNED_16;
audio_stream_type.channels = kSamplesPerFrame;
audio_stream_type.frames_per_second = kFramesPerSecond;
fuchsia::media::StreamType stream_type;
stream_type.medium_specific.set_audio(std::move(audio_stream_type));
stream_type.encoding = fuchsia::media::AUDIO_ENCODING_LPCM;
fuchsia::media::SimpleStreamSinkPtr sink;
elementary_source->AddStream(std::move(stream_type), kFramesPerSecond, 1, sink.NewRequest());
sink.set_error_handler([this](zx_status_t status) {
FX_LOGS(ERROR) << "SimpleStreamSink connection closed.";
sink_connection_closed_ = true;
QuitLoop();
});
sink_feeder_.Init(std::move(sink), kSinkFeedSize, kSamplesPerFrame * sizeof(int16_t),
kSinkFeedMaxPacketSize, kSinkFeedMaxPacketCount);
// Here we're upcasting from a
// |fidl::InterfaceHandle<fuchsia::media::playback::ElementarySource>| to a
// |fidl::InterfaceHandle<fuchsia::media::playback::Source>| the only way we
// currently can. The compiler has no way of knowing whether this is
// legit.
// TODO(dalesat): Do this safely once FIDL-329 is fixed.
player_->SetSource(fidl::InterfaceHandle<fuchsia::media::playback::Source>(
elementary_source.Unbind().TakeChannel()));
commands_.Play();
QuitOnEndOfStream();
Execute();
EXPECT_TRUE(fake_audio_.renderer().expected());
EXPECT_FALSE(sink_connection_closed_);
}
} // namespace test
} // namespace media_player