blob: 353502ed67f54c0ad7ef0ee728cfd21b8c763959 [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 "garnet/bin/flog_viewer/handlers/media_player.h"
#include <iostream>
#include "garnet/bin/flog_viewer/flog_viewer.h"
#include "garnet/bin/flog_viewer/handlers/media_formatting.h"
#include "lib/media/fidl/logs/media_player_channel.fidl.h"
namespace flog {
namespace handlers {
std::ostream& operator<<(std::ostream& os,
MediaPlayerAccumulator::State value) {
switch (value) {
case MediaPlayerAccumulator::State::kInitial:
return os << "initial";
case MediaPlayerAccumulator::State::kDescriptionReceived:
return os << "descriptionReceived";
case MediaPlayerAccumulator::State::kStreamsPrepared:
return os << "streamsPrepared";
case MediaPlayerAccumulator::State::kFlushed:
return os << "flushed";
case MediaPlayerAccumulator::State::kPriming:
return os << "priming";
case MediaPlayerAccumulator::State::kPrimed:
return os << "primed";
case MediaPlayerAccumulator::State::kPlaying:
return os << "playing";
case MediaPlayerAccumulator::State::kEndOfStream:
return os << "endOfStream";
case MediaPlayerAccumulator::State::kFlushing:
return os << "flushing";
}
return os;
}
MediaPlayer::MediaPlayer(const std::string& format)
: ChannelHandler(format),
accumulator_(std::make_shared<MediaPlayerAccumulator>()) {
stub_.set_sink(this);
}
MediaPlayer::~MediaPlayer() {}
void MediaPlayer::HandleMessage(fidl::Message* message) {
stub_.Accept(message);
}
std::shared_ptr<Accumulator> MediaPlayer::GetAccumulator() {
return accumulator_;
}
void MediaPlayer::BoundAs(uint64_t koid) {
terse_out() << EntryHeader(entry(), entry_index()) << "MediaPlayer.BoundAs\n";
terse_out() << indent;
terse_out() << begl << "koid: " << AsKoid(koid) << "\n";
terse_out() << outdent;
BindAs(koid);
}
void MediaPlayer::CreatedSource(uint64_t related_koid) {
terse_out() << EntryHeader(entry(), entry_index())
<< "MediaPlayer.CreatedSource\n";
terse_out() << indent;
terse_out() << begl << "related_koid: " << AsKoid(related_koid) << "\n";
terse_out() << outdent;
SetBindingKoid(&accumulator_->source_, related_koid);
}
void MediaPlayer::ReceivedSourceDescription(
fidl::Array<media::MediaTypePtr> stream_types) {
terse_out() << EntryHeader(entry(), entry_index())
<< "MediaPlayer.ReceivedSourceDescription"
<< "\n";
terse_out() << indent;
terse_out() << begl << "stream_types: " << stream_types << "\n";
terse_out() << outdent;
if (accumulator_->state_ != MediaPlayerAccumulator::State::kInitial) {
ReportProblem() << "ReceivedSourceDescription out of sequence";
} else {
accumulator_->state_ = MediaPlayerAccumulator::State::kDescriptionReceived;
}
if (accumulator_->stream_types_) {
ReportProblem() << "Duplicate ReceivedSourceDescription";
}
accumulator_->stream_types_ = std::move(stream_types);
accumulator_->sinks_.resize(accumulator_->stream_types_.size());
}
void MediaPlayer::CreatedSink(uint64_t stream_index, uint64_t related_koid) {
terse_out() << EntryHeader(entry(), entry_index())
<< "MediaPlayer.CreatedSink\n";
terse_out() << indent;
terse_out() << begl << "stream_index: " << stream_index << "\n";
terse_out() << begl << "related_koid: " << AsKoid(related_koid) << "\n";
terse_out() << outdent;
if (accumulator_->sinks_.size() <= stream_index) {
ReportProblem() << "Stream index (" << stream_index
<< ") out of range, stream count "
<< accumulator_->sinks_.size();
return;
}
SetBindingKoid(&accumulator_->sinks_[stream_index], related_koid);
}
void MediaPlayer::StreamsPrepared() {
terse_out() << EntryHeader(entry(), entry_index())
<< "MediaPlayer.StreamsPrepared\n";
if (accumulator_->state_ !=
MediaPlayerAccumulator::State::kDescriptionReceived) {
ReportProblem() << "StreamsPrepared out of sequence";
} else {
accumulator_->state_ = MediaPlayerAccumulator::State::kStreamsPrepared;
}
}
void MediaPlayer::Flushed() {
terse_out() << EntryHeader(entry(), entry_index()) << "MediaPlayer.Flushed\n";
if (accumulator_->state_ != MediaPlayerAccumulator::State::kFlushed &&
accumulator_->state_ != MediaPlayerAccumulator::State::kStreamsPrepared &&
accumulator_->state_ != MediaPlayerAccumulator::State::kFlushing) {
ReportProblem() << "Flushed out of sequence";
}
accumulator_->state_ = MediaPlayerAccumulator::State::kFlushed;
}
void MediaPlayer::ProgramRangeSet(uint64_t program,
int64_t min_pts,
int64_t max_pts) {
terse_out() << EntryHeader(entry(), entry_index())
<< "MediaPlayer.ProgramRangeSet\n";
terse_out() << indent;
terse_out() << begl << "program: " << program << "\n";
terse_out() << begl << "min_pts: " << AsNsTime(min_pts) << "\n";
terse_out() << begl << "max_pts: " << AsNsTime(max_pts) << "\n";
terse_out() << outdent;
if (accumulator_->state_ != MediaPlayerAccumulator::State::kFlushed &&
accumulator_->state_ != MediaPlayerAccumulator::State::kStreamsPrepared &&
accumulator_->state_ != MediaPlayerAccumulator::State::kFlushing) {
ReportProblem() << "Program range set out of sequence";
}
}
void MediaPlayer::Primed() {
terse_out() << EntryHeader(entry(), entry_index()) << "MediaPlayer.Primed\n";
if (accumulator_->state_ != MediaPlayerAccumulator::State::kPrimed &&
accumulator_->state_ != MediaPlayerAccumulator::State::kPriming &&
accumulator_->state_ != MediaPlayerAccumulator::State::kPlaying) {
ReportProblem() << "Primed out of sequence";
}
accumulator_->state_ = MediaPlayerAccumulator::State::kPrimed;
}
void MediaPlayer::Playing() {
terse_out() << EntryHeader(entry(), entry_index()) << "MediaPlayer.Playing\n";
if (accumulator_->state_ != MediaPlayerAccumulator::State::kPlaying &&
accumulator_->state_ != MediaPlayerAccumulator::State::kPrimed) {
ReportProblem() << "Playing out of sequence";
}
accumulator_->state_ = MediaPlayerAccumulator::State::kPlaying;
}
void MediaPlayer::EndOfStream() {
terse_out() << EntryHeader(entry(), entry_index())
<< "MediaPlayer.EndOfStream\n";
if (accumulator_->state_ != MediaPlayerAccumulator::State::kPrimed &&
accumulator_->state_ != MediaPlayerAccumulator::State::kPriming &&
accumulator_->state_ != MediaPlayerAccumulator::State::kPlaying) {
ReportProblem() << "EndOfStream out of sequence";
}
accumulator_->state_ = MediaPlayerAccumulator::State::kEndOfStream;
accumulator_->target_state_ = MediaPlayerAccumulator::State::kEndOfStream;
}
void MediaPlayer::PlayRequested() {
terse_out() << EntryHeader(entry(), entry_index())
<< "MediaPlayer.PlayRequested\n";
accumulator_->target_state_ = MediaPlayerAccumulator::State::kPlaying;
}
void MediaPlayer::PauseRequested() {
terse_out() << EntryHeader(entry(), entry_index())
<< "MediaPlayer.PauseRequested\n";
accumulator_->target_state_ = MediaPlayerAccumulator::State::kPrimed;
}
void MediaPlayer::SeekRequested(int64_t position) {
terse_out() << EntryHeader(entry(), entry_index())
<< "MediaPlayer.SeekRequested\n";
terse_out() << indent;
terse_out() << begl << "position: " << position << "\n";
terse_out() << outdent;
accumulator_->target_position_ = position;
}
void MediaPlayer::Seeking(int64_t position) {
terse_out() << EntryHeader(entry(), entry_index()) << "MediaPlayer.Seeking\n";
terse_out() << indent;
terse_out() << begl << "position: " << position << "\n";
terse_out() << outdent;
if (accumulator_->state_ != MediaPlayerAccumulator::State::kFlushed) {
ReportProblem() << "Seeking out of sequence";
}
if (accumulator_->target_position_ == media::kUnspecifiedTime) {
ReportProblem() << "Seeking with no SeekRequested";
}
accumulator_->target_position_ = media::kUnspecifiedTime;
}
void MediaPlayer::Priming() {
terse_out() << EntryHeader(entry(), entry_index()) << "MediaPlayer.Priming\n";
if (accumulator_->state_ != MediaPlayerAccumulator::State::kFlushed) {
ReportProblem() << "Priming out of sequence";
}
accumulator_->state_ = MediaPlayerAccumulator::State::kPriming;
}
void MediaPlayer::Flushing() {
terse_out() << EntryHeader(entry(), entry_index())
<< "MediaPlayer.Flushing\n";
if (accumulator_->state_ != MediaPlayerAccumulator::State::kPrimed &&
accumulator_->state_ != MediaPlayerAccumulator::State::kEndOfStream) {
ReportProblem() << "Flushing out of sequence";
}
accumulator_->state_ = MediaPlayerAccumulator::State::kFlushing;
}
void MediaPlayer::SettingTimelineTransform(
media::TimelineTransformPtr timeline_transform) {
terse_out() << EntryHeader(entry(), entry_index())
<< "MediaPlayer.SettingTimelineTransform\n";
terse_out() << indent;
terse_out() << begl << "timeline_transform: " << timeline_transform << "\n";
terse_out() << outdent;
if (accumulator_->state_ != MediaPlayerAccumulator::State::kPrimed &&
accumulator_->state_ != MediaPlayerAccumulator::State::kPlaying &&
accumulator_->state_ != MediaPlayerAccumulator::State::kEndOfStream) {
ReportProblem() << "SettingTimelineTransform out of sequence";
}
accumulator_->timeline_transform_ = std::move(timeline_transform);
}
MediaPlayerAccumulator::MediaPlayerAccumulator() {}
MediaPlayerAccumulator::~MediaPlayerAccumulator() {}
void MediaPlayerAccumulator::Print(std::ostream& os) {
os << "MediaPlayer\n";
os << indent;
os << begl << "state: " << state_ << "\n";
os << begl << "target_state: " << target_state_ << "\n";
os << begl << "target_position: " << AsNsTime(target_position_) << "\n";
os << begl << "source: " << source_ << "\n";
os << begl << "stream_types: " << stream_types_ << "\n";
os << begl << "sinks: " << sinks_ << "\n";
os << begl << "timeline_transform: " << timeline_transform_;
if (state_ != target_state_) {
os << "\n"
<< begl << "SUSPENSE: transitioning to state " << target_state_
<< ", currently in state " << state_;
}
if (target_position_ != media::kUnspecifiedTime) {
os << "\n" << begl << "SUSPENSE: seeking to position " << target_position_;
}
Accumulator::Print(os);
os << outdent;
}
} // namespace handlers
} // namespace flog