blob: d8fb6394a87772c53fef2bdf1ad10cce8750d76f [file] [log] [blame]
// Copyright 2020 The Chromium 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 "components/cast_streaming/browser/receiver_session_impl.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/video_decoder_config.h"
#include "media/mojo/mojom/media_types.mojom.h"
namespace cast_streaming {
// static
std::unique_ptr<ReceiverSession> ReceiverSession::Create(
std::unique_ptr<ReceiverSession::AVConstraints> av_constraints,
ReceiverSession::MessagePortProvider message_port_provider) {
return std::make_unique<ReceiverSessionImpl>(
std::move(av_constraints), std::move(message_port_provider));
}
ReceiverSessionImpl::ReceiverSessionImpl(
std::unique_ptr<ReceiverSession::AVConstraints> av_constraints,
ReceiverSession::MessagePortProvider message_port_provider)
: message_port_provider_(std::move(message_port_provider)),
av_constraints_(std::move(av_constraints)) {
// TODO(crbug.com/1218495): Validate the provided codecs against build flags.
DCHECK(av_constraints_);
DCHECK(message_port_provider_);
}
ReceiverSessionImpl::~ReceiverSessionImpl() = default;
void ReceiverSessionImpl::SetCastStreamingReceiver(
mojo::AssociatedRemote<mojom::CastStreamingReceiver>
cast_streaming_receiver) {
DVLOG(1) << __func__;
cast_streaming_receiver_ = std::move(cast_streaming_receiver);
// It is fine to use an unretained pointer to |this| here as the
// AssociatedRemote, is owned by |this| and will be torn-down at the same time
// as |this|.
cast_streaming_receiver_->EnableReceiver(base::BindOnce(
&ReceiverSessionImpl::OnReceiverEnabled, base::Unretained(this)));
cast_streaming_receiver_.set_disconnect_handler(base::BindOnce(
&ReceiverSessionImpl::OnMojoDisconnect, base::Unretained(this)));
}
void ReceiverSessionImpl::OnReceiverEnabled() {
DVLOG(1) << __func__;
DCHECK(message_port_provider_);
cast_streaming_session_.Start(this, std::move(av_constraints_),
std::move(message_port_provider_).Run(),
base::SequencedTaskRunnerHandle::Get());
}
void ReceiverSessionImpl::OnSessionInitialization(
absl::optional<cast_streaming::CastStreamingSession::AudioStreamInfo>
audio_stream_info,
absl::optional<cast_streaming::CastStreamingSession::VideoStreamInfo>
video_stream_info) {
DVLOG(1) << __func__;
DCHECK(audio_stream_info || video_stream_info);
mojom::AudioStreamInfoPtr mojo_audio_stream_info;
if (audio_stream_info) {
mojo_audio_stream_info =
mojom::AudioStreamInfo::New(audio_stream_info->decoder_config,
audio_remote_.BindNewPipeAndPassReceiver(),
std::move(audio_stream_info->data_pipe));
}
mojom::VideoStreamInfoPtr mojo_video_stream_info;
if (video_stream_info) {
mojo_video_stream_info =
mojom::VideoStreamInfo::New(video_stream_info->decoder_config,
video_remote_.BindNewPipeAndPassReceiver(),
std::move(video_stream_info->data_pipe));
}
cast_streaming_receiver_->OnStreamsInitialized(
std::move(mojo_audio_stream_info), std::move(mojo_video_stream_info));
}
void ReceiverSessionImpl::OnAudioBufferReceived(
media::mojom::DecoderBufferPtr buffer) {
DVLOG(3) << __func__;
DCHECK(audio_remote_);
audio_remote_->ProvideBuffer(std::move(buffer));
}
void ReceiverSessionImpl::OnVideoBufferReceived(
media::mojom::DecoderBufferPtr buffer) {
DVLOG(3) << __func__;
DCHECK(video_remote_);
video_remote_->ProvideBuffer(std::move(buffer));
}
void ReceiverSessionImpl::OnSessionReinitialization(
absl::optional<cast_streaming::CastStreamingSession::AudioStreamInfo>
audio_stream_info,
absl::optional<cast_streaming::CastStreamingSession::VideoStreamInfo>
video_stream_info) {
DVLOG(1) << __func__;
DCHECK(audio_stream_info || video_stream_info);
if (audio_stream_info) {
audio_remote_->OnNewAudioConfig(audio_stream_info->decoder_config,
std::move(audio_stream_info->data_pipe));
}
if (video_stream_info) {
video_remote_->OnNewVideoConfig(video_stream_info->decoder_config,
std::move(video_stream_info->data_pipe));
}
}
void ReceiverSessionImpl::OnSessionEnded() {
DVLOG(1) << __func__;
// Tear down the Mojo connection.
cast_streaming_receiver_.reset();
// Tear down all remaining Mojo objects if needed. This is necessary if the
// Cast Streaming Session ending was initiated by the receiver component.
if (audio_remote_)
audio_remote_.reset();
if (video_remote_)
video_remote_.reset();
}
void ReceiverSessionImpl::OnMojoDisconnect() {
DVLOG(1) << __func__;
// Close the underlying connection.
if (message_port_provider_) {
av_constraints_ = std::make_unique<ReceiverSession::AVConstraints>();
std::move(message_port_provider_).Run().reset();
}
// Close the Cast Streaming Session. OnSessionEnded() will be called as part
// of the Session shutdown, which will tear down the Mojo connection.
cast_streaming_session_.Stop();
// Tear down all remaining Mojo objects.
audio_remote_.reset();
video_remote_.reset();
}
} // namespace cast_streaming