Expose AV Settings outside cast_streaming Component
For use with other embedders aside from Fuchsia, the AV Settings (such as valid codecs, screen dimensions, etc...) must be exposed and set-able. This CL makes the following changes: - Expose the openscreen::cast::Preferences object as a top-level parameter for the embedder to provide. - Expose conversion utilities to be used by embedders in creating the above object - Add unit tests to the config conversions file. Bug: 1207721, internal b/182429089 Change-Id: I3af458b0491d2c413b1feee4801542c88e83bdb9 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2935034 Reviewed-by: Matthew Wolenetz <wolenetz@chromium.org> Reviewed-by: Fabrice de Gans <fdegans@chromium.org> Reviewed-by: Avi Drissman <avi@chromium.org> Reviewed-by: Mike West <mkwst@chromium.org> Commit-Queue: Ryan Keane <rwkeane@google.com> Cr-Commit-Position: refs/heads/master@{#893086}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
f9e2951503
commit
3381995478
components/cast_streaming
browser
BUILD.gncast_streaming_session.cccast_streaming_session.hconfig_conversions.ccconfig_conversions.h
public
receiver_session_impl.ccreceiver_session_impl.htest
public
fuchsia/engine
@ -22,16 +22,28 @@ source_set("core") {
|
||||
sources = [
|
||||
"cast_message_port_impl.cc",
|
||||
"cast_message_port_impl.h",
|
||||
"config_conversions.cc",
|
||||
"config_conversions.h",
|
||||
"message_serialization.cc",
|
||||
"message_serialization.h",
|
||||
]
|
||||
}
|
||||
|
||||
source_set("receiver_session_public") {
|
||||
deps = [
|
||||
"//base",
|
||||
"//mojo/public/cpp/system",
|
||||
]
|
||||
public_deps = [
|
||||
"//components/cast_streaming/public/mojom",
|
||||
"//third_party/openscreen/src/cast/streaming:receiver",
|
||||
]
|
||||
visibility = [ ":*" ]
|
||||
sources = [ "public/receiver_session.h" ]
|
||||
}
|
||||
|
||||
source_set("receiver_session") {
|
||||
deps = [
|
||||
":core",
|
||||
":receiver_session_public",
|
||||
":streaming_session",
|
||||
"//base",
|
||||
"//media",
|
||||
@ -41,10 +53,9 @@ source_set("receiver_session") {
|
||||
]
|
||||
public_deps = [
|
||||
"//components/cast_streaming/public/mojom",
|
||||
"//third_party/openscreen/src/cast/common:channel",
|
||||
"//third_party/openscreen/src/cast/streaming:receiver",
|
||||
]
|
||||
visibility = [ ":*" ]
|
||||
public = [ "public/receiver_session.h" ]
|
||||
sources = [
|
||||
"receiver_session_impl.cc",
|
||||
"receiver_session_impl.h",
|
||||
@ -54,7 +65,9 @@ source_set("receiver_session") {
|
||||
source_set("streaming_session") {
|
||||
deps = [
|
||||
":core",
|
||||
":receiver_session_public",
|
||||
"//base",
|
||||
"//components/cast_streaming/public",
|
||||
"//components/openscreen_platform",
|
||||
"//media",
|
||||
"//media/mojo/common",
|
||||
@ -84,13 +97,12 @@ source_set("network_context") {
|
||||
sources = [ "network_context_getter.cc" ]
|
||||
}
|
||||
|
||||
# TODO(crbug.com/1208194): Also move cast_streaming_session_client here from
|
||||
# //fuchsia.
|
||||
source_set("browser") {
|
||||
public_deps = [
|
||||
":network_context",
|
||||
":receiver_session",
|
||||
":receiver_session_public",
|
||||
]
|
||||
deps = [ ":receiver_session" ]
|
||||
}
|
||||
|
||||
# TODO(crbug.com/1207715): Move to /tests directory.
|
||||
@ -98,6 +110,7 @@ source_set("test_sender") {
|
||||
testonly = true
|
||||
deps = [
|
||||
":core",
|
||||
"//components/cast_streaming/public",
|
||||
"//media/mojo/common",
|
||||
"//media/mojo/mojom",
|
||||
"//mojo/public/cpp/system",
|
||||
@ -125,6 +138,7 @@ source_set("test_receiver") {
|
||||
deps = [
|
||||
":streaming_session",
|
||||
"//base",
|
||||
"//components/cast_streaming/public",
|
||||
"//components/openscreen_platform",
|
||||
"//media",
|
||||
"//media/mojo/common",
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/time/time.h"
|
||||
#include "components/cast_streaming/browser/config_conversions.h"
|
||||
#include "components/cast_streaming/browser/stream_consumer.h"
|
||||
#include "components/cast_streaming/public/config_conversions.h"
|
||||
#include "media/base/timestamp_constants.h"
|
||||
#include "media/mojo/common/mojo_decoder_buffer_converter.h"
|
||||
#include "mojo/public/cpp/system/data_pipe.h"
|
||||
@ -38,6 +38,7 @@ namespace cast_streaming {
|
||||
|
||||
CastStreamingSession::ReceiverSessionClient::ReceiverSessionClient(
|
||||
CastStreamingSession::Client* client,
|
||||
std::unique_ptr<ReceiverSession::AVConstraints> av_constraints,
|
||||
std::unique_ptr<cast_api_bindings::MessagePort> message_port,
|
||||
scoped_refptr<base::SequencedTaskRunner> task_runner)
|
||||
: task_runner_(task_runner),
|
||||
@ -51,15 +52,9 @@ CastStreamingSession::ReceiverSessionClient::ReceiverSessionClient(
|
||||
DCHECK(task_runner);
|
||||
DCHECK(client_);
|
||||
|
||||
// TODO(crbug.com/1087520): Add streaming session Constraints and
|
||||
// DisplayDescription.
|
||||
receiver_session_ = std::make_unique<openscreen::cast::ReceiverSession>(
|
||||
this, &environment_, &cast_message_port_impl_,
|
||||
openscreen::cast::ReceiverSession::Preferences(
|
||||
{openscreen::cast::VideoCodec::kH264,
|
||||
openscreen::cast::VideoCodec::kVp8},
|
||||
{openscreen::cast::AudioCodec::kAac,
|
||||
openscreen::cast::AudioCodec::kOpus}));
|
||||
std::move(*av_constraints));
|
||||
|
||||
init_timeout_timer_.Start(
|
||||
FROM_HERE, kInitTimeout,
|
||||
@ -102,9 +97,8 @@ CastStreamingSession::ReceiverSessionClient::InitializeAudioConsumer(
|
||||
base::BindRepeating(&base::OneShotTimer::Reset,
|
||||
base::Unretained(&data_timeout_timer_)));
|
||||
|
||||
return AudioStreamInfo{
|
||||
AudioCaptureConfigToAudioDecoderConfig(audio_capture_config),
|
||||
std::move(data_pipe_consumer)};
|
||||
return AudioStreamInfo{ToAudioDecoderConfig(audio_capture_config),
|
||||
std::move(data_pipe_consumer)};
|
||||
}
|
||||
|
||||
absl::optional<CastStreamingSession::VideoStreamInfo>
|
||||
@ -137,9 +131,8 @@ CastStreamingSession::ReceiverSessionClient::InitializeVideoConsumer(
|
||||
base::BindRepeating(&base::OneShotTimer::Reset,
|
||||
base::Unretained(&data_timeout_timer_)));
|
||||
|
||||
return VideoStreamInfo{
|
||||
VideoCaptureConfigToVideoDecoderConfig(video_capture_config),
|
||||
std::move(data_pipe_consumer)};
|
||||
return VideoStreamInfo{ToVideoDecoderConfig(video_capture_config),
|
||||
std::move(data_pipe_consumer)};
|
||||
}
|
||||
|
||||
void CastStreamingSession::ReceiverSessionClient::OnNegotiated(
|
||||
@ -266,13 +259,14 @@ CastStreamingSession::~CastStreamingSession() = default;
|
||||
|
||||
void CastStreamingSession::Start(
|
||||
Client* client,
|
||||
std::unique_ptr<ReceiverSession::AVConstraints> av_constraints,
|
||||
std::unique_ptr<cast_api_bindings::MessagePort> message_port,
|
||||
scoped_refptr<base::SequencedTaskRunner> task_runner) {
|
||||
DVLOG(1) << __func__;
|
||||
DCHECK(client);
|
||||
DCHECK(!receiver_session_);
|
||||
receiver_session_ = std::make_unique<ReceiverSessionClient>(
|
||||
client, std::move(message_port), task_runner);
|
||||
client, std::move(av_constraints), std::move(message_port), task_runner);
|
||||
}
|
||||
|
||||
void CastStreamingSession::Stop() {
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "base/timer/timer.h"
|
||||
#include "components/cast/message_port/message_port.h"
|
||||
#include "components/cast_streaming/browser/cast_message_port_impl.h"
|
||||
#include "components/cast_streaming/browser/public/receiver_session.h"
|
||||
#include "components/openscreen_platform/network_util.h"
|
||||
#include "components/openscreen_platform/task_runner.h"
|
||||
#include "media/base/audio_decoder_config.h"
|
||||
@ -85,7 +86,11 @@ class CastStreamingSession {
|
||||
// * On failure, OnSessionEnded() will be called.
|
||||
// * When a new offer is sent by the Cast Streaming Sender,
|
||||
// OnSessionReinitialization() will be called.
|
||||
//
|
||||
// |av_constraints| specifies the supported media codecs and limitations
|
||||
// surrounding this support.
|
||||
void Start(Client* client,
|
||||
std::unique_ptr<ReceiverSession::AVConstraints> av_constraints,
|
||||
std::unique_ptr<cast_api_bindings::MessagePort> message_port,
|
||||
scoped_refptr<base::SequencedTaskRunner> task_runner);
|
||||
|
||||
@ -101,6 +106,7 @@ class CastStreamingSession {
|
||||
public:
|
||||
ReceiverSessionClient(
|
||||
CastStreamingSession::Client* client,
|
||||
std::unique_ptr<ReceiverSession::AVConstraints> av_constraints,
|
||||
std::unique_ptr<cast_api_bindings::MessagePort> message_port,
|
||||
scoped_refptr<base::SequencedTaskRunner> task_runner);
|
||||
~ReceiverSessionClient() final;
|
||||
|
@ -1,112 +0,0 @@
|
||||
// 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/config_conversions.h"
|
||||
|
||||
#include "base/notreached.h"
|
||||
#include "media/base/media_util.h"
|
||||
|
||||
namespace cast_streaming {
|
||||
|
||||
openscreen::cast::AudioCaptureConfig AudioDecoderConfigToAudioCaptureConfig(
|
||||
const media::AudioDecoderConfig& audio_config) {
|
||||
openscreen::cast::AudioCaptureConfig audio_capture_config;
|
||||
|
||||
switch (audio_config.codec()) {
|
||||
case media::AudioCodec::kCodecAAC:
|
||||
audio_capture_config.codec = openscreen::cast::AudioCodec::kAac;
|
||||
break;
|
||||
case media::AudioCodec::kCodecOpus:
|
||||
audio_capture_config.codec = openscreen::cast::AudioCodec::kOpus;
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
audio_capture_config.channels =
|
||||
media::ChannelLayoutToChannelCount(audio_config.channel_layout());
|
||||
audio_capture_config.sample_rate = audio_config.samples_per_second();
|
||||
|
||||
return audio_capture_config;
|
||||
}
|
||||
|
||||
openscreen::cast::VideoCaptureConfig VideoDecoderConfigToVideoCaptureConfig(
|
||||
const media::VideoDecoderConfig& video_config) {
|
||||
openscreen::cast::VideoCaptureConfig video_capture_config;
|
||||
|
||||
switch (video_config.codec()) {
|
||||
case media::VideoCodec::kCodecH264:
|
||||
video_capture_config.codec = openscreen::cast::VideoCodec::kH264;
|
||||
break;
|
||||
case media::VideoCodec::kCodecVP8:
|
||||
video_capture_config.codec = openscreen::cast::VideoCodec::kVp8;
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
video_capture_config.resolutions.push_back(
|
||||
{video_config.visible_rect().width(),
|
||||
video_config.visible_rect().height()});
|
||||
return video_capture_config;
|
||||
}
|
||||
|
||||
media::AudioDecoderConfig AudioCaptureConfigToAudioDecoderConfig(
|
||||
const openscreen::cast::AudioCaptureConfig& audio_capture_config) {
|
||||
// Gather data for the audio decoder config.
|
||||
media::AudioCodec media_audio_codec = media::AudioCodec::kUnknownAudioCodec;
|
||||
switch (audio_capture_config.codec) {
|
||||
case openscreen::cast::AudioCodec::kAac:
|
||||
media_audio_codec = media::AudioCodec::kCodecAAC;
|
||||
break;
|
||||
case openscreen::cast::AudioCodec::kOpus:
|
||||
media_audio_codec = media::AudioCodec::kCodecOpus;
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
|
||||
return media::AudioDecoderConfig(
|
||||
media_audio_codec, media::SampleFormat::kSampleFormatF32,
|
||||
media::GuessChannelLayout(audio_capture_config.channels),
|
||||
audio_capture_config.sample_rate /* samples_per_second */,
|
||||
media::EmptyExtraData(), media::EncryptionScheme::kUnencrypted);
|
||||
}
|
||||
|
||||
media::VideoDecoderConfig VideoCaptureConfigToVideoDecoderConfig(
|
||||
const openscreen::cast::VideoCaptureConfig& video_capture_config) {
|
||||
// Gather data for the video decoder config.
|
||||
uint32_t video_width = video_capture_config.resolutions[0].width;
|
||||
uint32_t video_height = video_capture_config.resolutions[0].height;
|
||||
gfx::Size video_size(video_width, video_height);
|
||||
gfx::Rect video_rect(video_width, video_height);
|
||||
|
||||
media::VideoCodec media_video_codec = media::VideoCodec::kUnknownVideoCodec;
|
||||
media::VideoCodecProfile video_codec_profile =
|
||||
media::VideoCodecProfile::VIDEO_CODEC_PROFILE_UNKNOWN;
|
||||
switch (video_capture_config.codec) {
|
||||
case openscreen::cast::VideoCodec::kH264:
|
||||
media_video_codec = media::VideoCodec::kCodecH264;
|
||||
video_codec_profile = media::VideoCodecProfile::H264PROFILE_BASELINE;
|
||||
break;
|
||||
case openscreen::cast::VideoCodec::kVp8:
|
||||
media_video_codec = media::VideoCodec::kCodecVP8;
|
||||
video_codec_profile = media::VideoCodecProfile::VP8PROFILE_MIN;
|
||||
break;
|
||||
case openscreen::cast::VideoCodec::kHevc:
|
||||
case openscreen::cast::VideoCodec::kVp9:
|
||||
default:
|
||||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
|
||||
return media::VideoDecoderConfig(
|
||||
media_video_codec, video_codec_profile,
|
||||
media::VideoDecoderConfig::AlphaMode::kIsOpaque, media::VideoColorSpace(),
|
||||
media::VideoTransformation(), video_size, video_rect, video_size,
|
||||
media::EmptyExtraData(), media::EncryptionScheme::kUnencrypted);
|
||||
}
|
||||
|
||||
} // namespace cast_streaming
|
@ -1,30 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#ifndef COMPONENTS_CAST_STREAMING_BROWSER_CONFIG_CONVERSIONS_H_
|
||||
#define COMPONENTS_CAST_STREAMING_BROWSER_CONFIG_CONVERSIONS_H_
|
||||
|
||||
#include "media/base/audio_decoder_config.h"
|
||||
#include "media/base/video_decoder_config.h"
|
||||
#include "third_party/openscreen/src/cast/streaming/capture_configs.h"
|
||||
|
||||
namespace cast_streaming {
|
||||
|
||||
// Utility functions to convert between media and Open Screen types.
|
||||
|
||||
openscreen::cast::AudioCaptureConfig AudioDecoderConfigToAudioCaptureConfig(
|
||||
const media::AudioDecoderConfig& audio_config);
|
||||
|
||||
openscreen::cast::VideoCaptureConfig VideoDecoderConfigToVideoCaptureConfig(
|
||||
const media::VideoDecoderConfig& video_config);
|
||||
|
||||
media::AudioDecoderConfig AudioCaptureConfigToAudioDecoderConfig(
|
||||
const openscreen::cast::AudioCaptureConfig& audio_capture_config);
|
||||
|
||||
media::VideoDecoderConfig VideoCaptureConfigToVideoDecoderConfig(
|
||||
const openscreen::cast::VideoCaptureConfig& video_capture_config);
|
||||
|
||||
} // namespace cast_streaming
|
||||
|
||||
#endif // COMPONENTS_CAST_STREAMING_BROWSER_CONFIG_CONVERSIONS_H_
|
@ -10,6 +10,7 @@
|
||||
#include "base/callback.h"
|
||||
#include "components/cast_streaming/public/mojom/cast_streaming_session.mojom.h"
|
||||
#include "mojo/public/cpp/bindings/associated_remote.h"
|
||||
#include "third_party/openscreen/src/cast/streaming/receiver_session.h"
|
||||
|
||||
namespace cast_api_bindings {
|
||||
class MessagePort;
|
||||
@ -21,14 +22,25 @@ namespace cast_streaming {
|
||||
// |message_port| and with a given |cast_streaming_receiver|. On destruction,
|
||||
// the Cast Streaming Receiver Session will be terminated if it was ever
|
||||
// started.
|
||||
// TODO(1220176): Forward declare ReceiverSession::Preferences instead of
|
||||
// requiring the import above.
|
||||
class ReceiverSession {
|
||||
public:
|
||||
using MessagePortProvider =
|
||||
base::OnceCallback<std::unique_ptr<cast_api_bindings::MessagePort>()>;
|
||||
using AVConstraints = openscreen::cast::ReceiverSession::Preferences;
|
||||
|
||||
virtual ~ReceiverSession() = default;
|
||||
|
||||
// |av_constraints| specifies the supported media codecs, an ordering to
|
||||
// signify the receiver's preferences of which codecs should be used, and any
|
||||
// limitations surrounding this support.
|
||||
// |message_port_provider| creates a new MessagePort to be used for sending
|
||||
// and receiving Cast messages.
|
||||
// TODO(crbug.com/1219079): Add conversion functions to create the
|
||||
// ReceiverSession::Preferences object from //media types.
|
||||
static std::unique_ptr<ReceiverSession> Create(
|
||||
std::unique_ptr<AVConstraints> av_constraints,
|
||||
MessagePortProvider message_port_provider);
|
||||
|
||||
// Sets up the CastStreamingReceiver mojo remote. This will immediately call
|
||||
|
@ -13,14 +13,19 @@ 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(message_port_provider));
|
||||
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)) {
|
||||
: 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_);
|
||||
}
|
||||
|
||||
@ -44,7 +49,8 @@ void ReceiverSessionImpl::SetCastStreamingReceiver(
|
||||
void ReceiverSessionImpl::OnReceiverEnabled() {
|
||||
DVLOG(1) << __func__;
|
||||
DCHECK(message_port_provider_);
|
||||
cast_streaming_session_.Start(this, std::move(message_port_provider_).Run(),
|
||||
cast_streaming_session_.Start(this, std::move(av_constraints_),
|
||||
std::move(message_port_provider_).Run(),
|
||||
base::SequencedTaskRunnerHandle::Get());
|
||||
}
|
||||
|
||||
@ -128,6 +134,7 @@ void ReceiverSessionImpl::OnMojoDisconnect() {
|
||||
|
||||
// Close the underlying connection.
|
||||
if (message_port_provider_) {
|
||||
av_constraints_ = std::make_unique<ReceiverSession::AVConstraints>();
|
||||
std::move(message_port_provider_).Run().reset();
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,11 @@ namespace cast_streaming {
|
||||
class ReceiverSessionImpl : public cast_streaming::CastStreamingSession::Client,
|
||||
public ReceiverSession {
|
||||
public:
|
||||
explicit ReceiverSessionImpl(MessagePortProvider message_port_provider);
|
||||
// |av_constraints| specifies the supported media codecs and limitations
|
||||
// surrounding this support.
|
||||
ReceiverSessionImpl(
|
||||
std::unique_ptr<ReceiverSession::AVConstraints> av_constraints,
|
||||
MessagePortProvider message_port_provider);
|
||||
~ReceiverSessionImpl() final;
|
||||
|
||||
ReceiverSessionImpl(const ReceiverSessionImpl&) = delete;
|
||||
@ -55,6 +59,7 @@ class ReceiverSessionImpl : public cast_streaming::CastStreamingSession::Client,
|
||||
// Populated in the ctor, and empty following a call to either
|
||||
// OnReceiverEnabled() or OnMojoDisconnect().
|
||||
MessagePortProvider message_port_provider_;
|
||||
std::unique_ptr<ReceiverSession::AVConstraints> av_constraints_;
|
||||
|
||||
mojo::AssociatedRemote<mojom::CastStreamingReceiver> cast_streaming_receiver_;
|
||||
cast_streaming::CastStreamingSession cast_streaming_session_;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "base/logging.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/threading/sequenced_task_runner_handle.h"
|
||||
#include "components/cast_streaming/public/config_conversions.h"
|
||||
|
||||
namespace cast_streaming {
|
||||
|
||||
@ -16,7 +17,14 @@ CastStreamingTestReceiver::~CastStreamingTestReceiver() = default;
|
||||
void CastStreamingTestReceiver::Start(
|
||||
std::unique_ptr<cast_api_bindings::MessagePort> message_port) {
|
||||
VLOG(1) << __func__;
|
||||
receiver_session_.Start(this, std::move(message_port),
|
||||
auto stream_config =
|
||||
std::make_unique<cast_streaming::ReceiverSession::AVConstraints>(
|
||||
ToVideoCaptureConfigCodecs(media::VideoCodec::kCodecH264,
|
||||
media::VideoCodec::kCodecVP8),
|
||||
ToAudioCaptureConfigCodecs(media::AudioCodec::kCodecAAC,
|
||||
media::AudioCodec::kCodecOpus));
|
||||
receiver_session_.Start(this, std::move(stream_config),
|
||||
std::move(message_port),
|
||||
base::SequencedTaskRunnerHandle::Get());
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "base/logging.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/threading/sequenced_task_runner_handle.h"
|
||||
#include "components/cast_streaming/browser/config_conversions.h"
|
||||
#include "components/cast_streaming/public/config_conversions.h"
|
||||
#include "third_party/openscreen/src/cast/streaming/capture_recommendations.h"
|
||||
|
||||
namespace cast_streaming {
|
||||
@ -88,14 +88,12 @@ bool CastStreamingTestSender::Start(
|
||||
|
||||
std::vector<openscreen::cast::AudioCaptureConfig> audio_configs;
|
||||
if (audio_config) {
|
||||
audio_configs.push_back(
|
||||
AudioDecoderConfigToAudioCaptureConfig(audio_config.value()));
|
||||
audio_configs.push_back(ToAudioCaptureConfig(audio_config.value()));
|
||||
}
|
||||
|
||||
std::vector<openscreen::cast::VideoCaptureConfig> video_configs;
|
||||
if (video_config) {
|
||||
video_configs.push_back(
|
||||
VideoDecoderConfigToVideoCaptureConfig(video_config.value()));
|
||||
video_configs.push_back(ToVideoCaptureConfig(video_config.value()));
|
||||
}
|
||||
|
||||
openscreen::Error error = sender_session_->Negotiate(
|
||||
@ -191,14 +189,12 @@ void CastStreamingTestSender::OnNegotiated(
|
||||
|
||||
if (senders.audio_sender) {
|
||||
audio_sender_ = senders.audio_sender;
|
||||
audio_decoder_config_ =
|
||||
AudioCaptureConfigToAudioDecoderConfig(senders.audio_config);
|
||||
audio_decoder_config_ = ToAudioDecoderConfig(senders.audio_config);
|
||||
}
|
||||
|
||||
if (senders.video_sender) {
|
||||
video_sender_ = senders.video_sender;
|
||||
video_decoder_config_ =
|
||||
VideoCaptureConfigToVideoDecoderConfig(senders.video_config);
|
||||
video_decoder_config_ = ToVideoDecoderConfig(senders.video_config);
|
||||
}
|
||||
|
||||
is_active_ = true;
|
||||
|
@ -5,18 +5,33 @@
|
||||
import("//testing/test.gni")
|
||||
|
||||
source_set("public") {
|
||||
deps = [ "//url" ]
|
||||
deps = [
|
||||
"//base",
|
||||
"//media",
|
||||
"//ui/gfx/geometry",
|
||||
"//url",
|
||||
]
|
||||
public_deps = [
|
||||
"//third_party/openscreen/src/cast/streaming:receiver",
|
||||
"//third_party/openscreen/src/cast/streaming:streaming_configs",
|
||||
]
|
||||
sources = [
|
||||
"cast_streaming_url.cc",
|
||||
"cast_streaming_url.h",
|
||||
"config_conversions.cc",
|
||||
"config_conversions.h",
|
||||
]
|
||||
}
|
||||
|
||||
# NOTE: This source set is intentionally empty. It is used to force the building
|
||||
# of the code defined in this directory, as it is production code which must
|
||||
# be validated as part of the CQ.
|
||||
source_set("unit_tests") {
|
||||
testonly = true
|
||||
deps = [ ":public" ]
|
||||
sources = []
|
||||
deps = [
|
||||
":public",
|
||||
"//base/test:test_support",
|
||||
"//media:test_support",
|
||||
"//media/mojo:test_support",
|
||||
"//testing/gmock",
|
||||
"//testing/gtest",
|
||||
]
|
||||
sources = [ "config_conversions_unittest.cc" ]
|
||||
}
|
||||
|
6
components/cast_streaming/public/DEPS
Normal file
6
components/cast_streaming/public/DEPS
Normal file
@ -0,0 +1,6 @@
|
||||
include_rules = [
|
||||
"+media/base",
|
||||
"+third_party/openscreen/src/cast",
|
||||
"+ui/gfx/geometry",
|
||||
"+url",
|
||||
]
|
166
components/cast_streaming/public/config_conversions.cc
Normal file
166
components/cast_streaming/public/config_conversions.cc
Normal file
@ -0,0 +1,166 @@
|
||||
// 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/public/config_conversions.h"
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/notreached.h"
|
||||
#include "media/base/media_util.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/gfx/geometry/size.h"
|
||||
|
||||
namespace cast_streaming {
|
||||
namespace {
|
||||
|
||||
media::VideoCodecProfile ToVideoDecoderConfigCodecProfile(
|
||||
openscreen::cast::VideoCodec codec) {
|
||||
switch (codec) {
|
||||
// TODO(b/186875732): Determine the values for Hevc and Vp9 experimentally.
|
||||
case openscreen::cast::VideoCodec::kH264:
|
||||
return media::VideoCodecProfile::H264PROFILE_BASELINE;
|
||||
case openscreen::cast::VideoCodec::kHevc:
|
||||
return media::VideoCodecProfile::HEVCPROFILE_MAIN;
|
||||
case openscreen::cast::VideoCodec::kVp8:
|
||||
return media::VideoCodecProfile::VP8PROFILE_MIN;
|
||||
case openscreen::cast::VideoCodec::kVp9:
|
||||
return media::VideoCodecProfile::VP9PROFILE_PROFILE0;
|
||||
case openscreen::cast::VideoCodec::kNotSpecified:
|
||||
break;
|
||||
}
|
||||
|
||||
NOTREACHED();
|
||||
return media::VideoCodecProfile::VIDEO_CODEC_PROFILE_UNKNOWN;
|
||||
}
|
||||
|
||||
media::AudioCodec ToAudioDecoderConfigCodec(
|
||||
openscreen::cast::AudioCodec codec) {
|
||||
switch (codec) {
|
||||
case openscreen::cast::AudioCodec::kAac:
|
||||
return media::AudioCodec::kCodecAAC;
|
||||
case openscreen::cast::AudioCodec::kOpus:
|
||||
return media::AudioCodec::kCodecOpus;
|
||||
case openscreen::cast::AudioCodec::kNotSpecified:
|
||||
break;
|
||||
}
|
||||
|
||||
NOTREACHED();
|
||||
return media::AudioCodec::kUnknownAudioCodec;
|
||||
}
|
||||
|
||||
media::VideoCodec ToVideoDecoderConfigCodec(
|
||||
openscreen::cast::VideoCodec codec) {
|
||||
switch (codec) {
|
||||
case openscreen::cast::VideoCodec::kH264:
|
||||
return media::VideoCodec::kCodecH264;
|
||||
case openscreen::cast::VideoCodec::kVp8:
|
||||
return media::VideoCodec::kCodecVP8;
|
||||
case openscreen::cast::VideoCodec::kHevc:
|
||||
return media::VideoCodec::kCodecHEVC;
|
||||
case openscreen::cast::VideoCodec::kVp9:
|
||||
return media::VideoCodec::kCodecVP9;
|
||||
case openscreen::cast::VideoCodec::kNotSpecified:
|
||||
break;
|
||||
}
|
||||
|
||||
NOTREACHED();
|
||||
return media::VideoCodec::kUnknownVideoCodec;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
openscreen::cast::AudioCodec ToAudioCaptureConfigCodec(
|
||||
media::AudioCodec codec) {
|
||||
switch (codec) {
|
||||
case media::AudioCodec::kCodecAAC:
|
||||
return openscreen::cast::AudioCodec::kAac;
|
||||
case media::AudioCodec::kCodecOpus:
|
||||
return openscreen::cast::AudioCodec::kOpus;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NOTREACHED();
|
||||
return openscreen::cast::AudioCodec::kNotSpecified;
|
||||
}
|
||||
|
||||
openscreen::cast::VideoCodec ToVideoCaptureConfigCodec(
|
||||
media::VideoCodec codec) {
|
||||
switch (codec) {
|
||||
case media::VideoCodec::kCodecH264:
|
||||
return openscreen::cast::VideoCodec::kH264;
|
||||
case media::VideoCodec::kCodecVP8:
|
||||
return openscreen::cast::VideoCodec::kVp8;
|
||||
case media::VideoCodec::kCodecHEVC:
|
||||
return openscreen::cast::VideoCodec::kHevc;
|
||||
case media::VideoCodec::kCodecVP9:
|
||||
return openscreen::cast::VideoCodec::kVp9;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NOTREACHED();
|
||||
return openscreen::cast::VideoCodec::kNotSpecified;
|
||||
}
|
||||
|
||||
openscreen::cast::AudioCaptureConfig ToAudioCaptureConfig(
|
||||
const media::AudioDecoderConfig& audio_config) {
|
||||
DCHECK(!audio_config.is_encrypted());
|
||||
|
||||
openscreen::cast::AudioCaptureConfig audio_capture_config;
|
||||
audio_capture_config.codec = ToAudioCaptureConfigCodec(audio_config.codec());
|
||||
audio_capture_config.channels =
|
||||
media::ChannelLayoutToChannelCount(audio_config.channel_layout());
|
||||
audio_capture_config.sample_rate = audio_config.samples_per_second();
|
||||
audio_capture_config.bit_rate = 0; // Selected by the sender.
|
||||
|
||||
return audio_capture_config;
|
||||
}
|
||||
|
||||
openscreen::cast::VideoCaptureConfig ToVideoCaptureConfig(
|
||||
const media::VideoDecoderConfig& video_config) {
|
||||
DCHECK(!video_config.is_encrypted());
|
||||
|
||||
openscreen::cast::VideoCaptureConfig video_capture_config;
|
||||
video_capture_config.codec = ToVideoCaptureConfigCodec(video_config.codec());
|
||||
video_capture_config.resolutions.push_back(
|
||||
{video_config.visible_rect().width(),
|
||||
video_config.visible_rect().height()});
|
||||
video_capture_config.max_bit_rate = 0; // Selected by the sender.
|
||||
return video_capture_config;
|
||||
}
|
||||
|
||||
media::AudioDecoderConfig ToAudioDecoderConfig(
|
||||
const openscreen::cast::AudioCaptureConfig& audio_capture_config) {
|
||||
media::AudioCodec media_audio_codec =
|
||||
ToAudioDecoderConfigCodec(audio_capture_config.codec);
|
||||
|
||||
return media::AudioDecoderConfig(
|
||||
media_audio_codec, media::SampleFormat::kSampleFormatF32,
|
||||
media::GuessChannelLayout(audio_capture_config.channels),
|
||||
audio_capture_config.sample_rate /* samples_per_second */,
|
||||
media::EmptyExtraData(), media::EncryptionScheme::kUnencrypted);
|
||||
}
|
||||
|
||||
media::VideoDecoderConfig ToVideoDecoderConfig(
|
||||
const openscreen::cast::VideoCaptureConfig& video_capture_config) {
|
||||
// Gather data for the video decoder config.
|
||||
DCHECK(video_capture_config.resolutions.size());
|
||||
uint32_t video_width = video_capture_config.resolutions[0].width;
|
||||
uint32_t video_height = video_capture_config.resolutions[0].height;
|
||||
gfx::Size video_size(video_width, video_height);
|
||||
gfx::Rect video_rect(video_width, video_height);
|
||||
|
||||
media::VideoCodec media_video_codec =
|
||||
ToVideoDecoderConfigCodec(video_capture_config.codec);
|
||||
media::VideoCodecProfile video_codec_profile =
|
||||
ToVideoDecoderConfigCodecProfile(video_capture_config.codec);
|
||||
|
||||
return media::VideoDecoderConfig(
|
||||
media_video_codec, video_codec_profile,
|
||||
media::VideoDecoderConfig::AlphaMode::kIsOpaque, media::VideoColorSpace(),
|
||||
media::VideoTransformation(), video_size, video_rect, video_size,
|
||||
media::EmptyExtraData(), media::EncryptionScheme::kUnencrypted);
|
||||
}
|
||||
|
||||
} // namespace cast_streaming
|
50
components/cast_streaming/public/config_conversions.h
Normal file
50
components/cast_streaming/public/config_conversions.h
Normal file
@ -0,0 +1,50 @@
|
||||
// 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.
|
||||
|
||||
#ifndef COMPONENTS_CAST_STREAMING_PUBLIC_CONFIG_CONVERSIONS_H_
|
||||
#define COMPONENTS_CAST_STREAMING_PUBLIC_CONFIG_CONVERSIONS_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "media/base/audio_decoder_config.h"
|
||||
#include "media/base/video_decoder_config.h"
|
||||
#include "third_party/openscreen/src/cast/streaming/capture_configs.h"
|
||||
|
||||
namespace cast_streaming {
|
||||
|
||||
// Utility functions to convert between media and Open Screen types.
|
||||
|
||||
openscreen::cast::AudioCaptureConfig ToAudioCaptureConfig(
|
||||
const media::AudioDecoderConfig& audio_config);
|
||||
|
||||
openscreen::cast::VideoCaptureConfig ToVideoCaptureConfig(
|
||||
const media::VideoDecoderConfig& video_config);
|
||||
|
||||
media::AudioDecoderConfig ToAudioDecoderConfig(
|
||||
const openscreen::cast::AudioCaptureConfig& audio_capture_config);
|
||||
|
||||
media::VideoDecoderConfig ToVideoDecoderConfig(
|
||||
const openscreen::cast::VideoCaptureConfig& video_capture_config);
|
||||
|
||||
openscreen::cast::AudioCodec ToAudioCaptureConfigCodec(media::AudioCodec codec);
|
||||
|
||||
openscreen::cast::VideoCodec ToVideoCaptureConfigCodec(media::VideoCodec codec);
|
||||
|
||||
template <typename... TCodecs>
|
||||
std::vector<openscreen::cast::AudioCodec> ToAudioCaptureConfigCodecs(
|
||||
TCodecs... codecs) {
|
||||
return std::vector<openscreen::cast::AudioCodec>{
|
||||
ToAudioCaptureConfigCodec(codecs)...};
|
||||
}
|
||||
|
||||
template <typename... TCodecs>
|
||||
std::vector<openscreen::cast::VideoCodec> ToVideoCaptureConfigCodecs(
|
||||
TCodecs... codecs) {
|
||||
return std::vector<openscreen::cast::VideoCodec>{
|
||||
ToVideoCaptureConfigCodec(codecs)...};
|
||||
}
|
||||
|
||||
} // namespace cast_streaming
|
||||
|
||||
#endif // COMPONENTS_CAST_STREAMING_PUBLIC_CONFIG_CONVERSIONS_H_
|
241
components/cast_streaming/public/config_conversions_unittest.cc
Normal file
241
components/cast_streaming/public/config_conversions_unittest.cc
Normal file
@ -0,0 +1,241 @@
|
||||
// Copyright 2021 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/public/config_conversions.h"
|
||||
|
||||
#include "media/base/media_util.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "third_party/openscreen/src/cast/streaming/capture_configs.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/gfx/geometry/size.h"
|
||||
|
||||
namespace cast_streaming {
|
||||
namespace {
|
||||
|
||||
void ValidateAudioConfig(const media::AudioDecoderConfig& config,
|
||||
const media::AudioDecoderConfig& expected) {
|
||||
EXPECT_EQ(config.codec(), expected.codec());
|
||||
EXPECT_EQ(config.sample_format(), media::SampleFormat::kSampleFormatF32);
|
||||
EXPECT_EQ(config.channel_layout(), expected.channel_layout());
|
||||
EXPECT_EQ(config.samples_per_second(), expected.samples_per_second());
|
||||
EXPECT_EQ(config.extra_data().size(), size_t{0});
|
||||
EXPECT_FALSE(config.is_encrypted());
|
||||
}
|
||||
|
||||
void ValidateAudioConfig(const openscreen::cast::AudioCaptureConfig& config,
|
||||
const openscreen::cast::AudioCaptureConfig& expected) {
|
||||
EXPECT_EQ(config.codec, expected.codec);
|
||||
EXPECT_EQ(config.channels, expected.channels);
|
||||
EXPECT_EQ(config.bit_rate, expected.bit_rate);
|
||||
EXPECT_EQ(config.sample_rate, expected.sample_rate);
|
||||
EXPECT_EQ(config.target_playout_delay, expected.target_playout_delay);
|
||||
}
|
||||
|
||||
void ValidateVideoConfig(const media::VideoDecoderConfig& config,
|
||||
const media::VideoDecoderConfig& expected) {
|
||||
EXPECT_EQ(config.codec(), expected.codec());
|
||||
EXPECT_EQ(config.profile(), expected.profile());
|
||||
EXPECT_EQ(config.alpha_mode(),
|
||||
media::VideoDecoderConfig::AlphaMode::kIsOpaque);
|
||||
EXPECT_EQ(config.extra_data().size(), size_t{0});
|
||||
EXPECT_FALSE(config.is_encrypted());
|
||||
|
||||
EXPECT_EQ(config.coded_size().width(), expected.coded_size().width());
|
||||
EXPECT_EQ(config.coded_size().height(), expected.coded_size().height());
|
||||
|
||||
EXPECT_EQ(config.visible_rect().width(), expected.visible_rect().width());
|
||||
EXPECT_EQ(config.visible_rect().height(), expected.visible_rect().height());
|
||||
|
||||
EXPECT_EQ(config.natural_size().width(), expected.natural_size().width());
|
||||
EXPECT_EQ(config.natural_size().height(), expected.natural_size().height());
|
||||
}
|
||||
|
||||
void ValidateVideoConfig(const openscreen::cast::VideoCaptureConfig& config,
|
||||
const openscreen::cast::VideoCaptureConfig& expected) {
|
||||
EXPECT_EQ(config.codec, expected.codec);
|
||||
EXPECT_EQ(config.max_frame_rate, expected.max_frame_rate);
|
||||
EXPECT_EQ(config.max_bit_rate, expected.max_bit_rate);
|
||||
EXPECT_EQ(config.target_playout_delay, expected.target_playout_delay);
|
||||
ASSERT_EQ(config.resolutions.size(), expected.resolutions.size());
|
||||
for (const auto& resolution : config.resolutions) {
|
||||
EXPECT_TRUE(std::find(expected.resolutions.begin(),
|
||||
expected.resolutions.end(),
|
||||
resolution) != expected.resolutions.end());
|
||||
}
|
||||
}
|
||||
|
||||
openscreen::cast::AudioCaptureConfig CreateAudioCaptureConfig() {
|
||||
openscreen::cast::AudioCaptureConfig config;
|
||||
config.codec = openscreen::cast::AudioCodec::kAac;
|
||||
config.channels = 2;
|
||||
config.sample_rate = 42;
|
||||
return config;
|
||||
}
|
||||
|
||||
media::AudioDecoderConfig CreateAudioDecoderConfig(
|
||||
media::AudioCodec codec,
|
||||
media::ChannelLayout channel_layout,
|
||||
int samples_per_second) {
|
||||
return media::AudioDecoderConfig(codec, media::SampleFormat::kSampleFormatF32,
|
||||
channel_layout, samples_per_second,
|
||||
media::EmptyExtraData(),
|
||||
media::EncryptionScheme::kUnencrypted);
|
||||
}
|
||||
|
||||
openscreen::cast::VideoCaptureConfig CreateVideoCaptureConfig() {
|
||||
openscreen::cast::VideoCaptureConfig config;
|
||||
config.codec = openscreen::cast::VideoCodec::kH264;
|
||||
config.resolutions.push_back({1080, 720});
|
||||
return config;
|
||||
}
|
||||
|
||||
media::VideoDecoderConfig CreateVideoDecoderConfig(
|
||||
media::VideoCodec codec,
|
||||
media::VideoCodecProfile codec_profile,
|
||||
int width,
|
||||
int height) {
|
||||
gfx::Size video_size(width, height);
|
||||
gfx::Rect video_rect(width, height);
|
||||
return media::VideoDecoderConfig(
|
||||
codec, codec_profile, media::VideoDecoderConfig::AlphaMode::kIsOpaque,
|
||||
media::VideoColorSpace(), media::VideoTransformation(), video_size,
|
||||
video_rect, video_size, media::EmptyExtraData(),
|
||||
media::EncryptionScheme::kUnencrypted);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(ConfigConversionsTest, AudioConfigCodecConversion) {
|
||||
auto capture_config = CreateAudioCaptureConfig();
|
||||
auto decoder_config =
|
||||
CreateAudioDecoderConfig(media::AudioCodec::kCodecAAC,
|
||||
media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 42);
|
||||
ValidateAudioConfig(ToAudioDecoderConfig(capture_config), decoder_config);
|
||||
ValidateAudioConfig(ToAudioCaptureConfig(decoder_config), capture_config);
|
||||
|
||||
capture_config.codec = openscreen::cast::AudioCodec::kOpus;
|
||||
decoder_config =
|
||||
CreateAudioDecoderConfig(media::AudioCodec::kCodecOpus,
|
||||
media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 42);
|
||||
ValidateAudioConfig(ToAudioDecoderConfig(capture_config), decoder_config);
|
||||
ValidateAudioConfig(ToAudioCaptureConfig(decoder_config), capture_config);
|
||||
}
|
||||
|
||||
TEST(ConfigConversionsTest, AudioConfigChannelsConversion) {
|
||||
auto capture_config = CreateAudioCaptureConfig();
|
||||
auto decoder_config =
|
||||
CreateAudioDecoderConfig(media::AudioCodec::kCodecAAC,
|
||||
media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 42);
|
||||
ValidateAudioConfig(ToAudioDecoderConfig(capture_config), decoder_config);
|
||||
ValidateAudioConfig(ToAudioCaptureConfig(decoder_config), capture_config);
|
||||
|
||||
capture_config.channels = 1;
|
||||
decoder_config =
|
||||
CreateAudioDecoderConfig(media::AudioCodec::kCodecAAC,
|
||||
media::ChannelLayout::CHANNEL_LAYOUT_MONO, 42);
|
||||
ValidateAudioConfig(ToAudioDecoderConfig(capture_config), decoder_config);
|
||||
ValidateAudioConfig(ToAudioCaptureConfig(decoder_config), capture_config);
|
||||
|
||||
// Other configurations are not expected in practice.
|
||||
}
|
||||
|
||||
TEST(ConfigConversionsTest, AudioConfigSampleRateConversion) {
|
||||
auto capture_config = CreateAudioCaptureConfig();
|
||||
auto decoder_config =
|
||||
CreateAudioDecoderConfig(media::AudioCodec::kCodecAAC,
|
||||
media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 42);
|
||||
ValidateAudioConfig(ToAudioDecoderConfig(capture_config), decoder_config);
|
||||
ValidateAudioConfig(ToAudioCaptureConfig(decoder_config), capture_config);
|
||||
|
||||
capture_config.sample_rate = 1234;
|
||||
decoder_config = CreateAudioDecoderConfig(
|
||||
media::AudioCodec::kCodecAAC, media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
|
||||
1234);
|
||||
ValidateAudioConfig(ToAudioDecoderConfig(capture_config), decoder_config);
|
||||
ValidateAudioConfig(ToAudioCaptureConfig(decoder_config), capture_config);
|
||||
|
||||
capture_config.sample_rate = -1;
|
||||
decoder_config =
|
||||
CreateAudioDecoderConfig(media::AudioCodec::kCodecAAC,
|
||||
media::ChannelLayout::CHANNEL_LAYOUT_STEREO, -1);
|
||||
ValidateAudioConfig(ToAudioDecoderConfig(capture_config), decoder_config);
|
||||
ValidateAudioConfig(ToAudioCaptureConfig(decoder_config), capture_config);
|
||||
|
||||
capture_config.sample_rate = 0;
|
||||
decoder_config =
|
||||
CreateAudioDecoderConfig(media::AudioCodec::kCodecAAC,
|
||||
media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 0);
|
||||
ValidateAudioConfig(ToAudioDecoderConfig(capture_config), decoder_config);
|
||||
ValidateAudioConfig(ToAudioCaptureConfig(decoder_config), capture_config);
|
||||
}
|
||||
|
||||
TEST(ConfigConversionsTest, VideoConfigCodecConversion) {
|
||||
const int width = 1080;
|
||||
const int height = 720;
|
||||
auto capture_config = CreateVideoCaptureConfig();
|
||||
auto decoder_config = CreateVideoDecoderConfig(
|
||||
media::VideoCodec::kCodecH264,
|
||||
media::VideoCodecProfile::H264PROFILE_BASELINE, width, height);
|
||||
ValidateVideoConfig(ToVideoDecoderConfig(capture_config), decoder_config);
|
||||
ValidateVideoConfig(ToVideoCaptureConfig(decoder_config), capture_config);
|
||||
|
||||
capture_config.codec = openscreen::cast::VideoCodec::kVp8;
|
||||
decoder_config = CreateVideoDecoderConfig(
|
||||
media::VideoCodec::kCodecVP8, media::VideoCodecProfile::VP8PROFILE_MIN,
|
||||
width, height);
|
||||
ValidateVideoConfig(ToVideoDecoderConfig(capture_config), decoder_config);
|
||||
ValidateVideoConfig(ToVideoCaptureConfig(decoder_config), capture_config);
|
||||
|
||||
capture_config.codec = openscreen::cast::VideoCodec::kHevc;
|
||||
decoder_config = CreateVideoDecoderConfig(
|
||||
media::VideoCodec::kCodecHEVC, media::VideoCodecProfile::HEVCPROFILE_MAIN,
|
||||
width, height);
|
||||
ValidateVideoConfig(ToVideoDecoderConfig(capture_config), decoder_config);
|
||||
ValidateVideoConfig(ToVideoCaptureConfig(decoder_config), capture_config);
|
||||
|
||||
capture_config.codec = openscreen::cast::VideoCodec::kVp9;
|
||||
decoder_config = CreateVideoDecoderConfig(
|
||||
media::VideoCodec::kCodecVP9,
|
||||
media::VideoCodecProfile::VP9PROFILE_PROFILE0, width, height);
|
||||
ValidateVideoConfig(ToVideoDecoderConfig(capture_config), decoder_config);
|
||||
ValidateVideoConfig(ToVideoCaptureConfig(decoder_config), capture_config);
|
||||
}
|
||||
|
||||
TEST(ConfigConversionsTest, VideoConfigResolutionConversion) {
|
||||
auto capture_config = CreateVideoCaptureConfig();
|
||||
auto decoder_config = CreateVideoDecoderConfig(
|
||||
media::VideoCodec::kCodecH264,
|
||||
media::VideoCodecProfile::H264PROFILE_BASELINE, 1080, 720);
|
||||
ValidateVideoConfig(ToVideoDecoderConfig(capture_config), decoder_config);
|
||||
ValidateVideoConfig(ToVideoCaptureConfig(decoder_config), capture_config);
|
||||
|
||||
ASSERT_EQ(capture_config.resolutions.size(), size_t{1});
|
||||
|
||||
capture_config.resolutions[0].width = 42;
|
||||
capture_config.resolutions[0].height = 16;
|
||||
decoder_config = CreateVideoDecoderConfig(
|
||||
media::VideoCodec::kCodecH264,
|
||||
media::VideoCodecProfile::H264PROFILE_BASELINE, 42, 16);
|
||||
ValidateVideoConfig(ToVideoDecoderConfig(capture_config), decoder_config);
|
||||
ValidateVideoConfig(ToVideoCaptureConfig(decoder_config), capture_config);
|
||||
|
||||
capture_config.resolutions[0].width = 1;
|
||||
capture_config.resolutions[0].height = 2;
|
||||
decoder_config = CreateVideoDecoderConfig(
|
||||
media::VideoCodec::kCodecH264,
|
||||
media::VideoCodecProfile::H264PROFILE_BASELINE, 1, 2);
|
||||
ValidateVideoConfig(ToVideoDecoderConfig(capture_config), decoder_config);
|
||||
ValidateVideoConfig(ToVideoCaptureConfig(decoder_config), capture_config);
|
||||
|
||||
capture_config.resolutions[0].width = 0;
|
||||
capture_config.resolutions[0].height = 0;
|
||||
decoder_config = CreateVideoDecoderConfig(
|
||||
media::VideoCodec::kCodecH264,
|
||||
media::VideoCodecProfile::H264PROFILE_BASELINE, 0, 0);
|
||||
ValidateVideoConfig(ToVideoDecoderConfig(capture_config), decoder_config);
|
||||
ValidateVideoConfig(ToVideoCaptureConfig(decoder_config), capture_config);
|
||||
}
|
||||
|
||||
} // namespace cast_streaming
|
@ -104,6 +104,7 @@ component("web_engine_core") {
|
||||
"//base/util/memory_pressure",
|
||||
"//components/cast/message_port:message_port_fuchsia",
|
||||
"//components/cast_streaming/browser",
|
||||
"//components/cast_streaming/public",
|
||||
"//components/cast_streaming/public/mojom",
|
||||
"//components/cast_streaming/renderer",
|
||||
"//components/cdm/renderer",
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "components/cast/message_port/message_port_fuchsia.h"
|
||||
#include "components/cast_streaming/public/config_conversions.h"
|
||||
#include "media/base/audio_decoder_config.h"
|
||||
#include "media/base/video_decoder_config.h"
|
||||
|
||||
ReceiverSessionClient::ReceiverSessionClient(
|
||||
fidl::InterfaceRequest<fuchsia::web::MessagePort> message_port_request)
|
||||
@ -20,12 +23,26 @@ void ReceiverSessionClient::SetCastStreamingReceiver(
|
||||
cast_streaming_receiver) {
|
||||
DCHECK(message_port_request_);
|
||||
|
||||
receiver_session_ = cast_streaming::ReceiverSession::Create(base::BindOnce(
|
||||
[](fidl::InterfaceRequest<fuchsia::web::MessagePort> port)
|
||||
-> std::unique_ptr<cast_api_bindings::MessagePort> {
|
||||
return cast_api_bindings::MessagePortFuchsia::Create(std::move(port));
|
||||
},
|
||||
std::move(message_port_request_)));
|
||||
// TODO: Add streaming session Constraints based on system capabilities
|
||||
// (see crbug.com/1013412) and DisplayDescription (see crbug.com/1087520).
|
||||
// TODO(crbug.com/1218498): Only populate codecs corresponding to those called
|
||||
// out by build flags.
|
||||
auto stream_config =
|
||||
std::make_unique<cast_streaming::ReceiverSession::AVConstraints>(
|
||||
cast_streaming::ToVideoCaptureConfigCodecs(
|
||||
media::VideoCodec::kCodecH264, media::VideoCodec::kCodecVP8),
|
||||
cast_streaming::ToAudioCaptureConfigCodecs(
|
||||
media::AudioCodec::kCodecAAC, media::AudioCodec::kCodecOpus));
|
||||
|
||||
receiver_session_ = cast_streaming::ReceiverSession::Create(
|
||||
std::move(stream_config),
|
||||
base::BindOnce(
|
||||
[](fidl::InterfaceRequest<fuchsia::web::MessagePort> port)
|
||||
-> std::unique_ptr<cast_api_bindings::MessagePort> {
|
||||
return cast_api_bindings::MessagePortFuchsia::Create(
|
||||
std::move(port));
|
||||
},
|
||||
std::move(message_port_request_)));
|
||||
receiver_session_->SetCastStreamingReceiver(
|
||||
std::move(cast_streaming_receiver));
|
||||
}
|
||||
|
Reference in New Issue
Block a user