aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbraham Corea Diaz <abrahamcd@google.com>2021-07-16 20:22:50 +0000
committerOpenscreen LUCI CQ <openscreen-scoped@luci-project-accounts.iam.gserviceaccount.com>2021-07-16 23:47:30 +0000
commitb2074333b14325c183a3bc66cb7e1af881e67663 (patch)
tree1664c33beef9e191a186379de96e79082cc2fbf1
parent4f20671877f4b0d515641cbb566c4c0fe4a2c947 (diff)
downloadopenscreen-b2074333b14325c183a3bc66cb7e1af881e67663.tar.gz
Enable VP9 codec in standalone sender and receiver
This patch adds support for the VP9 video codec by modifying the former streaming VP8 encoder to a general streaming VPX encoder that handles both VP8 and VP9. It also adds a command line argument to the sender to allow choosing which codec to use. Change-Id: Ia254df071c37dddcbe8ea136aaaee47bc8db80a2 Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/3028642 Reviewed-by: Jordan Bayles <jophba@chromium.org> Reviewed-by: mark a. foltz <mfoltz@chromium.org> Commit-Queue: mark a. foltz <mfoltz@chromium.org>
-rw-r--r--cast/standalone_receiver/mirroring_application.cc2
-rw-r--r--cast/standalone_sender/BUILD.gn4
-rw-r--r--cast/standalone_sender/connection_settings.h4
-rw-r--r--cast/standalone_sender/looping_file_cast_agent.cc13
-rw-r--r--cast/standalone_sender/looping_file_sender.cc7
-rw-r--r--cast/standalone_sender/looping_file_sender.h4
-rw-r--r--cast/standalone_sender/main.cc24
-rw-r--r--cast/standalone_sender/streaming_vpx_encoder.cc (renamed from cast/standalone_sender/streaming_vp8_encoder.cc)54
-rw-r--r--cast/standalone_sender/streaming_vpx_encoder.h (renamed from cast/standalone_sender/streaming_vp8_encoder.h)25
-rw-r--r--cast/streaming/receiver_message.cc22
-rw-r--r--cast/streaming/receiver_message.h3
-rw-r--r--cast/streaming/receiver_session.cc2
12 files changed, 108 insertions, 56 deletions
diff --git a/cast/standalone_receiver/mirroring_application.cc b/cast/standalone_receiver/mirroring_application.cc
index 83921d76..683fad5d 100644
--- a/cast/standalone_receiver/mirroring_application.cc
+++ b/cast/standalone_receiver/mirroring_application.cc
@@ -57,6 +57,8 @@ bool MirroringApplication::Launch(const std::string& app_id,
std::make_unique<StreamingPlaybackController>(task_runner_, this);
ReceiverSession::Preferences preferences;
+ preferences.video_codecs.insert(preferences.video_codecs.end(),
+ {VideoCodec::kVp9, VideoCodec::kAv1});
preferences.remoting =
std::make_unique<ReceiverSession::RemotingPreferences>();
current_session_ =
diff --git a/cast/standalone_sender/BUILD.gn b/cast/standalone_sender/BUILD.gn
index 780e0609..b00e769d 100644
--- a/cast/standalone_sender/BUILD.gn
+++ b/cast/standalone_sender/BUILD.gn
@@ -55,8 +55,8 @@ if (!build_with_chromium) {
"simulated_capturer.h",
"streaming_opus_encoder.cc",
"streaming_opus_encoder.h",
- "streaming_vp8_encoder.cc",
- "streaming_vp8_encoder.h",
+ "streaming_vpx_encoder.cc",
+ "streaming_vpx_encoder.h",
]
include_dirs +=
ffmpeg_include_dirs + libopus_include_dirs + libvpx_include_dirs
diff --git a/cast/standalone_sender/connection_settings.h b/cast/standalone_sender/connection_settings.h
index f42842c3..4c7e4849 100644
--- a/cast/standalone_sender/connection_settings.h
+++ b/cast/standalone_sender/connection_settings.h
@@ -7,6 +7,7 @@
#include <string>
+#include "cast/streaming/constants.h"
#include "platform/base/interface_info.h"
namespace openscreen {
@@ -40,6 +41,9 @@ struct ConnectionSettings {
// Whether we should loop the video when it is completed.
bool should_loop_video = true;
+
+ // The codec to use for encoding negotiated video streams.
+ VideoCodec codec;
};
} // namespace cast
diff --git a/cast/standalone_sender/looping_file_cast_agent.cc b/cast/standalone_sender/looping_file_cast_agent.cc
index bfb970bf..4ee2231a 100644
--- a/cast/standalone_sender/looping_file_cast_agent.cc
+++ b/cast/standalone_sender/looping_file_cast_agent.cc
@@ -260,10 +260,11 @@ void LoopingFileCastAgent::CreateAndStartSession() {
AudioCaptureConfig audio_config;
// Opus does best at 192kbps, so we cap that here.
audio_config.bit_rate = 192 * 1000;
- VideoCaptureConfig video_config;
- // The video config is allowed to use whatever is left over after audio.
- video_config.max_bit_rate =
- connection_settings_->max_bitrate - audio_config.bit_rate;
+ VideoCaptureConfig video_config = {
+ .codec = connection_settings_->codec,
+ // The video config is allowed to use whatever is left over after audio.
+ .max_bit_rate =
+ connection_settings_->max_bitrate - audio_config.bit_rate};
// Use default display resolution of 1080P.
video_config.resolutions.emplace_back(Resolution{1920, 1080});
@@ -271,8 +272,8 @@ void LoopingFileCastAgent::CreateAndStartSession() {
Error negotiation_error;
if (connection_settings_->use_remoting) {
remoting_sender_ = std::make_unique<RemotingSender>(
- current_session_->rpc_messenger(), AudioCodec::kOpus, VideoCodec::kVp8,
- [this]() { OnRemotingReceiverReady(); });
+ current_session_->rpc_messenger(), AudioCodec::kOpus,
+ connection_settings_->codec, [this]() { OnRemotingReceiverReady(); });
negotiation_error =
current_session_->NegotiateRemoting(audio_config, video_config);
diff --git a/cast/standalone_sender/looping_file_sender.cc b/cast/standalone_sender/looping_file_sender.cc
index 1392c413..9f6137dc 100644
--- a/cast/standalone_sender/looping_file_sender.cc
+++ b/cast/standalone_sender/looping_file_sender.cc
@@ -23,7 +23,7 @@ LoopingFileSender::LoopingFileSender(Environment* environment,
audio_encoder_(senders.audio_sender->config().channels,
StreamingOpusEncoder::kDefaultCastAudioFramesPerSecond,
senders.audio_sender),
- video_encoder_(StreamingVp8Encoder::Parameters{},
+ video_encoder_(StreamingVpxEncoder::Parameters{.codec = settings.codec},
env_->task_runner(),
senders.video_sender),
next_task_(env_->now_function(), env_->task_runner()),
@@ -32,7 +32,8 @@ LoopingFileSender::LoopingFileSender(Environment* environment,
// to a different value that means we offered a codec that we do not
// support, which is a developer error.
OSP_CHECK(senders.audio_config.codec == AudioCodec::kOpus);
- OSP_CHECK(senders.video_config.codec == VideoCodec::kVp8);
+ OSP_CHECK(senders.video_config.codec == VideoCodec::kVp8 ||
+ senders.video_config.codec == VideoCodec::kVp9);
OSP_LOG_INFO << "Max allowed media bitrate (audio + video) will be "
<< settings_.max_bitrate;
bandwidth_being_utilized_ = settings_.max_bitrate / 2;
@@ -117,7 +118,7 @@ void LoopingFileSender::OnVideoFrame(const AVFrame& av_frame,
Clock::time_point capture_time) {
TRACE_DEFAULT_SCOPED(TraceCategory::kStandaloneSender);
latest_frame_time_ = std::max(capture_time, latest_frame_time_);
- StreamingVp8Encoder::VideoFrame frame{};
+ StreamingVpxEncoder::VideoFrame frame{};
frame.width = av_frame.width - av_frame.crop_left - av_frame.crop_right;
frame.height = av_frame.height - av_frame.crop_top - av_frame.crop_bottom;
frame.yuv_planes[0] = av_frame.data[0] + av_frame.crop_left +
diff --git a/cast/standalone_sender/looping_file_sender.h b/cast/standalone_sender/looping_file_sender.h
index ef283dc3..56a8aa45 100644
--- a/cast/standalone_sender/looping_file_sender.h
+++ b/cast/standalone_sender/looping_file_sender.h
@@ -12,7 +12,7 @@
#include "cast/standalone_sender/constants.h"
#include "cast/standalone_sender/simulated_capturer.h"
#include "cast/standalone_sender/streaming_opus_encoder.h"
-#include "cast/standalone_sender/streaming_vp8_encoder.h"
+#include "cast/standalone_sender/streaming_vpx_encoder.h"
#include "cast/streaming/sender_session.h"
namespace openscreen {
@@ -73,7 +73,7 @@ class LoopingFileSender final : public SimulatedAudioCapturer::Client,
int bandwidth_being_utilized_;
StreamingOpusEncoder audio_encoder_;
- StreamingVp8Encoder video_encoder_;
+ StreamingVpxEncoder video_encoder_;
int num_capturers_running_ = 0;
Clock::time_point capture_start_time_{};
diff --git a/cast/standalone_sender/main.cc b/cast/standalone_sender/main.cc
index 228c00b1..22a9b6fa 100644
--- a/cast/standalone_sender/main.cc
+++ b/cast/standalone_sender/main.cc
@@ -81,6 +81,9 @@ usage: %s <options> addr[:port] media_file
-v, --verbose: Enable verbose logging.
-h, --help: Show this help message.
+
+ -c, --codec: Specifies the video codec to be used. Can be one of:
+ vp8, vp9, av1. Defaults to vp8 if not specified.
)";
std::cerr << StringPrintf(kTemplate, argv0, argv0, kDefaultCastPort,
@@ -122,6 +125,7 @@ int StandaloneSenderMain(int argc, char* argv[]) {
{"tracing", no_argument, nullptr, 't'},
{"verbose", no_argument, nullptr, 'v'},
{"help", no_argument, nullptr, 'h'},
+ {"codec", required_argument, nullptr, 'c'},
{nullptr, 0, nullptr, 0}
};
@@ -131,9 +135,10 @@ int StandaloneSenderMain(int argc, char* argv[]) {
bool use_android_rtp_hack = false;
bool use_remoting = false;
bool is_verbose = false;
+ VideoCodec codec = VideoCodec::kVp8;
std::unique_ptr<TextTraceLoggingPlatform> trace_logger;
int ch = -1;
- while ((ch = getopt_long(argc, argv, "m:nd:artvh", kArgumentOptions,
+ while ((ch = getopt_long(argc, argv, "m:nd:artvhc:", kArgumentOptions,
nullptr)) != -1) {
switch (ch) {
case 'm':
@@ -168,6 +173,20 @@ int StandaloneSenderMain(int argc, char* argv[]) {
case 'h':
LogUsage(argv[0]);
return 1;
+ case 'c':
+ auto specified_codec = StringToVideoCodec(optarg);
+ if (specified_codec.is_value() &&
+ (specified_codec.value() == VideoCodec::kVp8 ||
+ specified_codec.value() == VideoCodec::kVp9 ||
+ specified_codec.value() == VideoCodec::kAv1)) {
+ codec = specified_codec.value();
+ } else {
+ OSP_LOG_ERROR << "Invalid --codec specified: " << optarg
+ << " is not one of: vp8, vp9, av1.";
+ LogUsage(argv[0]);
+ return 1;
+ }
+ break;
}
}
@@ -228,7 +247,8 @@ int StandaloneSenderMain(int argc, char* argv[]) {
.should_include_video = true,
.use_android_rtp_hack = use_android_rtp_hack,
.use_remoting = use_remoting,
- .should_loop_video = should_loop_video});
+ .should_loop_video = should_loop_video,
+ .codec = codec});
});
// Run the event loop until SIGINT (e.g., CTRL-C at the console) or
diff --git a/cast/standalone_sender/streaming_vp8_encoder.cc b/cast/standalone_sender/streaming_vpx_encoder.cc
index 7cc10e35..1c9de314 100644
--- a/cast/standalone_sender/streaming_vp8_encoder.cc
+++ b/cast/standalone_sender/streaming_vpx_encoder.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "cast/standalone_sender/streaming_vp8_encoder.h"
+#include "cast/standalone_sender/streaming_vpx_encoder.h"
#include <stdint.h>
#include <string.h>
@@ -49,7 +49,7 @@ constexpr double kEquivalentEncodingSpeedStepPerQuantizerStep = 1 / 20.0;
} // namespace
-StreamingVp8Encoder::StreamingVp8Encoder(const Parameters& params,
+StreamingVpxEncoder::StreamingVpxEncoder(const Parameters& params,
TaskRunner* task_runner,
Sender* sender)
: params_(params),
@@ -67,8 +67,15 @@ StreamingVp8Encoder::StreamingVp8Encoder(const Parameters& params,
OSP_DCHECK(main_task_runner_);
OSP_DCHECK(sender_);
- const auto result =
- vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &config_, 0);
+ vpx_codec_iface_t* ctx;
+ if (params_.codec == VideoCodec::kVp9) {
+ ctx = vpx_codec_vp9_cx();
+ } else {
+ OSP_DCHECK(params_.codec == VideoCodec::kVp8);
+ ctx = vpx_codec_vp8_cx();
+ }
+
+ const auto result = vpx_codec_enc_config_default(ctx, &config_, 0);
OSP_CHECK_EQ(result, VPX_CODEC_OK);
// This is set to non-zero in ConfigureForNewFrameSize() later, to flag that
@@ -104,7 +111,7 @@ StreamingVp8Encoder::StreamingVp8Encoder(const Parameters& params,
config_.kf_mode = VPX_KF_DISABLED;
}
-StreamingVp8Encoder::~StreamingVp8Encoder() {
+StreamingVpxEncoder::~StreamingVpxEncoder() {
{
std::unique_lock<std::mutex> lock(mutex_);
target_bitrate_ = 0;
@@ -113,13 +120,13 @@ StreamingVp8Encoder::~StreamingVp8Encoder() {
encode_thread_.join();
}
-int StreamingVp8Encoder::GetTargetBitrate() const {
+int StreamingVpxEncoder::GetTargetBitrate() const {
// Note: No need to lock the |mutex_| since this method should be called on
// the same thread as SetTargetBitrate().
return target_bitrate_;
}
-void StreamingVp8Encoder::SetTargetBitrate(int new_bitrate) {
+void StreamingVpxEncoder::SetTargetBitrate(int new_bitrate) {
// Ensure that, when bps is converted to kbps downstream, that the encoder
// bitrate will not be zero.
new_bitrate = std::max(new_bitrate, kBytesPerKilobyte);
@@ -132,7 +139,7 @@ void StreamingVp8Encoder::SetTargetBitrate(int new_bitrate) {
}
}
-void StreamingVp8Encoder::EncodeAndSend(
+void StreamingVpxEncoder::EncodeAndSend(
const VideoFrame& frame,
Clock::time_point reference_time,
std::function<void(Stats)> stats_callback) {
@@ -194,7 +201,7 @@ void StreamingVp8Encoder::EncodeAndSend(
}
}
-void StreamingVp8Encoder::DestroyEncoder() {
+void StreamingVpxEncoder::DestroyEncoder() {
OSP_DCHECK_EQ(std::this_thread::get_id(), encode_thread_.get_id());
if (is_encoder_initialized()) {
@@ -205,7 +212,7 @@ void StreamingVp8Encoder::DestroyEncoder() {
}
}
-void StreamingVp8Encoder::ProcessWorkUnitsUntilTimeToQuit() {
+void StreamingVpxEncoder::ProcessWorkUnitsUntilTimeToQuit() {
OSP_DCHECK_EQ(std::this_thread::get_id(), encode_thread_.get_id());
for (;;) {
@@ -249,7 +256,7 @@ void StreamingVp8Encoder::ProcessWorkUnitsUntilTimeToQuit() {
DestroyEncoder();
}
-void StreamingVp8Encoder::PrepareEncoder(int width,
+void StreamingVpxEncoder::PrepareEncoder(int width,
int height,
int target_bitrate) {
OSP_DCHECK_EQ(std::this_thread::get_id(), encode_thread_.get_id());
@@ -287,8 +294,17 @@ void StreamingVp8Encoder::PrepareEncoder(int width,
encoder_ = {};
const vpx_codec_flags_t flags = 0;
+
+ vpx_codec_iface_t* ctx;
+ if (params_.codec == VideoCodec::kVp9) {
+ ctx = vpx_codec_vp9_cx();
+ } else {
+ OSP_DCHECK(params_.codec == VideoCodec::kVp8);
+ ctx = vpx_codec_vp8_cx();
+ }
+
const auto init_result =
- vpx_codec_enc_init(&encoder_, vpx_codec_vp8_cx(), &config_, flags);
+ vpx_codec_enc_init(&encoder_, ctx, &config_, flags);
OSP_CHECK_EQ(init_result, VPX_CODEC_OK);
// Raise the threshold for considering macroblocks as static. The default is
@@ -311,7 +327,7 @@ void StreamingVp8Encoder::PrepareEncoder(int width,
}
if (current_speed_setting_ != speed) {
- // Pass the |speed| as a negative value to turn off VP8's automatic speed
+ // Pass the |speed| as a negative value to turn off VP8/9's automatic speed
// selection logic and force the exact setting.
const auto ctl_result =
vpx_codec_control(&encoder_, VP8E_SET_CPUUSED, -speed);
@@ -320,7 +336,7 @@ void StreamingVp8Encoder::PrepareEncoder(int width,
}
}
-void StreamingVp8Encoder::EncodeFrame(bool force_key_frame,
+void StreamingVpxEncoder::EncodeFrame(bool force_key_frame,
WorkUnitWithResults* work_unit) {
OSP_DCHECK_EQ(std::this_thread::get_id(), encode_thread_.get_id());
@@ -354,7 +370,7 @@ void StreamingVp8Encoder::EncodeFrame(bool force_key_frame,
work_unit->is_key_frame = !!(pkt->data.frame.flags & VPX_FRAME_IS_KEY);
}
-void StreamingVp8Encoder::ComputeFrameEncodeStats(
+void StreamingVpxEncoder::ComputeFrameEncodeStats(
Clock::duration encode_wall_time,
int target_bitrate,
WorkUnitWithResults* work_unit) {
@@ -375,7 +391,7 @@ void StreamingVp8Encoder::ComputeFrameEncodeStats(
target_bitrate * (kBytesPerBit * kSecondsPerClockTick);
stats.target_size = target_bytes_per_clock_tick * work_unit->duration.count();
- // The quantizer the encoder used. This is the result of the VP8 encoder
+ // The quantizer the encoder used. This is the result of the VP8/9 encoder
// taking a guess at what quantizer value would produce an encoded frame size
// as close to the target as possible.
const auto get_quantizer_result = vpx_codec_control(
@@ -388,7 +404,7 @@ void StreamingVp8Encoder::ComputeFrameEncodeStats(
stats.perfect_quantizer = stats.quantizer * stats.space_utilization();
}
-void StreamingVp8Encoder::UpdateSpeedSettingForNextFrame(const Stats& stats) {
+void StreamingVpxEncoder::UpdateSpeedSettingForNextFrame(const Stats& stats) {
OSP_DCHECK_EQ(std::this_thread::get_id(), encode_thread_.get_id());
// Combine the speed setting that was used to encode the last frame, and the
@@ -415,7 +431,7 @@ void StreamingVp8Encoder::UpdateSpeedSettingForNextFrame(const Stats& stats) {
OSP_DCHECK(std::isfinite(ideal_speed_setting_));
}
-void StreamingVp8Encoder::SendEncodedFrame(WorkUnitWithResults results) {
+void StreamingVpxEncoder::SendEncodedFrame(WorkUnitWithResults results) {
OSP_DCHECK(main_task_runner_->IsRunningOnTaskRunner());
EncodedFrame frame;
@@ -464,7 +480,7 @@ void CopyPlane(const uint8_t* src,
} // namespace
// static
-StreamingVp8Encoder::VpxImageUniquePtr StreamingVp8Encoder::CloneAsVpxImage(
+StreamingVpxEncoder::VpxImageUniquePtr StreamingVpxEncoder::CloneAsVpxImage(
const VideoFrame& frame) {
OSP_DCHECK_GE(frame.width, 0);
OSP_DCHECK_GE(frame.height, 0);
diff --git a/cast/standalone_sender/streaming_vp8_encoder.h b/cast/standalone_sender/streaming_vpx_encoder.h
index c5d52248..6935efdd 100644
--- a/cast/standalone_sender/streaming_vp8_encoder.h
+++ b/cast/standalone_sender/streaming_vpx_encoder.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CAST_STANDALONE_SENDER_STREAMING_VP8_ENCODER_H_
-#define CAST_STANDALONE_SENDER_STREAMING_VP8_ENCODER_H_
+#ifndef CAST_STANDALONE_SENDER_STREAMING_VPX_ENCODER_H_
+#define CAST_STANDALONE_SENDER_STREAMING_VPX_ENCODER_H_
#include <vpx/vpx_encoder.h>
#include <vpx/vpx_image.h>
@@ -18,6 +18,7 @@
#include <vector>
#include "absl/base/thread_annotations.h"
+#include "cast/streaming/constants.h"
#include "cast/streaming/frame_id.h"
#include "cast/streaming/rtp_time.h"
#include "platform/api/task_runner.h"
@@ -31,7 +32,7 @@ namespace cast {
class Sender;
-// Uses libvpx to encode VP8 video and streams it to a Sender. Includes
+// Uses libvpx to encode VP8/9 video and streams it to a Sender. Includes
// extensive logic for fine-tuning the encoder parameters in real-time, to
// provide the best quality results given external, uncontrollable factors:
// CPU/network availability, and the complexity of the video frame content.
@@ -52,9 +53,9 @@ class Sender;
// to further optimize the user experience. For example, the stats can be used
// as a signal to reduce the data volume (i.e., resolution and/or frame rate)
// coming from the video capture source.
-class StreamingVp8Encoder {
+class StreamingVpxEncoder {
public:
- // Configurable parameters passed to the StreamingVp8Encoder constructor.
+ // Configurable parameters passed to the StreamingVpxEncoder constructor.
struct Parameters {
// Number of threads to parallelize frame encoding. This should be set based
// on the number of CPU cores available for encoding, but no more than 8.
@@ -80,6 +81,10 @@ class StreamingVp8Encoder {
// and a value of 0.5 here would mean that the CPU-saver logic starts
// sacrificing quality when frame encodes start taking longer than ~16.7ms.
double max_time_utilization = 0.7;
+
+ // Determines which codec (VP8 or VP9) is to be used for encoding. Defaults
+ // to VP8.
+ VideoCodec codec = VideoCodec::kVp8;
};
// Represents an input VideoFrame, passed to EncodeAndSend().
@@ -95,7 +100,7 @@ class StreamingVp8Encoder {
int yuv_strides[3];
// How long this frame will be held before the next frame will be displayed,
- // or zero if unknown. The frame duration is passed to the VP8 codec,
+ // or zero if unknown. The frame duration is passed to the VP8/9 codec,
// affecting a number of important behaviors, including: per-frame
// bandwidth, CPU time spent encoding, temporal quality trade-offs, and
// key/golden/alt-ref frame generation intervals.
@@ -161,11 +166,11 @@ class StreamingVp8Encoder {
}
};
- StreamingVp8Encoder(const Parameters& params,
+ StreamingVpxEncoder(const Parameters& params,
TaskRunner* task_runner,
Sender* sender);
- ~StreamingVp8Encoder();
+ ~StreamingVpxEncoder();
// Get/Set the target bitrate. This may be changed at any time, as frequently
// as desired, and it will take effect internally as soon as possible.
@@ -288,7 +293,7 @@ class StreamingVp8Encoder {
double ideal_speed_setting_; // A time-weighted average, from measurements.
int current_speed_setting_; // Current |encoder_| speed setting.
- // libvpx VP8 encoder instance. Only the encode thread accesses this.
+ // libvpx VP8/9 encoder instance. Only the encode thread accesses this.
vpx_codec_ctx_t encoder_;
// This member should be last in the class since the thread should not start
@@ -299,4 +304,4 @@ class StreamingVp8Encoder {
} // namespace cast
} // namespace openscreen
-#endif // CAST_STANDALONE_SENDER_STREAMING_VP8_ENCODER_H_
+#endif // CAST_STANDALONE_SENDER_STREAMING_VPX_ENCODER_H_
diff --git a/cast/streaming/receiver_message.cc b/cast/streaming/receiver_message.cc
index 4fb1a8a6..7f0999f0 100644
--- a/cast/streaming/receiver_message.cc
+++ b/cast/streaming/receiver_message.cc
@@ -27,17 +27,17 @@ EnumNameTable<ReceiverMessage::Type, 5> kMessageTypeNames{
{"CAPABILITIES_RESPONSE", ReceiverMessage::Type::kCapabilitiesResponse},
{"RPC", ReceiverMessage::Type::kRpc}}};
-EnumNameTable<MediaCapability, 9> kMediaCapabilityNames{{
- {"audio", MediaCapability::kAudio},
- {"aac", MediaCapability::kAac},
- {"opus", MediaCapability::kOpus},
- {"video", MediaCapability::kVideo},
- {"4k", MediaCapability::k4k},
- {"h264", MediaCapability::kH264},
- {"vp8", MediaCapability::kVp8},
- {"vp9", MediaCapability::kVp9},
- {"hevc", MediaCapability::kHevc},
-}};
+EnumNameTable<MediaCapability, 10> kMediaCapabilityNames{
+ {{"audio", MediaCapability::kAudio},
+ {"aac", MediaCapability::kAac},
+ {"opus", MediaCapability::kOpus},
+ {"video", MediaCapability::kVideo},
+ {"4k", MediaCapability::k4k},
+ {"h264", MediaCapability::kH264},
+ {"vp8", MediaCapability::kVp8},
+ {"vp9", MediaCapability::kVp9},
+ {"hevc", MediaCapability::kHevc},
+ {"av1", MediaCapability::kAv1}}};
ReceiverMessage::Type GetMessageType(const Json::Value& root) {
std::string type;
diff --git a/cast/streaming/receiver_message.h b/cast/streaming/receiver_message.h
index e25a64bd..f4adbfb3 100644
--- a/cast/streaming/receiver_message.h
+++ b/cast/streaming/receiver_message.h
@@ -26,7 +26,8 @@ enum class MediaCapability {
kH264,
kVp8,
kVp9,
- kHevc
+ kHevc,
+ kAv1
};
struct ReceiverCapability {
diff --git a/cast/streaming/receiver_session.cc b/cast/streaming/receiver_session.cc
index b55784b2..bda6d984 100644
--- a/cast/streaming/receiver_session.cc
+++ b/cast/streaming/receiver_session.cc
@@ -68,6 +68,8 @@ MediaCapability ToCapability(VideoCodec codec) {
return MediaCapability::kH264;
case VideoCodec::kHevc:
return MediaCapability::kHevc;
+ case VideoCodec::kAv1:
+ return MediaCapability::kAv1;
default:
OSP_DLOG_FATAL << "Invalid video codec: " << static_cast<int>(codec);
OSP_NOTREACHED();