aboutsummaryrefslogtreecommitdiff
path: root/modules/video_coding/codecs/av1
diff options
context:
space:
mode:
Diffstat (limited to 'modules/video_coding/codecs/av1')
-rw-r--r--modules/video_coding/codecs/av1/av1_svc_config.cc3
-rw-r--r--modules/video_coding/codecs/av1/av1_svc_config_unittest.cc8
-rw-r--r--modules/video_coding/codecs/av1/libaom_av1_encoder.cc25
-rw-r--r--modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc32
4 files changed, 62 insertions, 6 deletions
diff --git a/modules/video_coding/codecs/av1/av1_svc_config.cc b/modules/video_coding/codecs/av1/av1_svc_config.cc
index 1e61477b78..b15443c563 100644
--- a/modules/video_coding/codecs/av1/av1_svc_config.cc
+++ b/modules/video_coding/codecs/av1/av1_svc_config.cc
@@ -51,8 +51,9 @@ bool SetAv1SvcConfig(VideoCodec& video_codec) {
if (info.num_spatial_layers == 1) {
SpatialLayer& spatial_layer = video_codec.spatialLayers[0];
spatial_layer.minBitrate = video_codec.minBitrate;
- spatial_layer.targetBitrate = video_codec.startBitrate;
spatial_layer.maxBitrate = video_codec.maxBitrate;
+ spatial_layer.targetBitrate =
+ (video_codec.minBitrate + video_codec.maxBitrate) / 2;
return true;
}
diff --git a/modules/video_coding/codecs/av1/av1_svc_config_unittest.cc b/modules/video_coding/codecs/av1/av1_svc_config_unittest.cc
index 02ded1c70d..e6035328da 100644
--- a/modules/video_coding/codecs/av1/av1_svc_config_unittest.cc
+++ b/modules/video_coding/codecs/av1/av1_svc_config_unittest.cc
@@ -97,19 +97,21 @@ TEST(Av1SvcConfigTest, SetsNumberOfTemporalLayers) {
EXPECT_EQ(video_codec.spatialLayers[0].numberOfTemporalLayers, 3);
}
-TEST(Av1SvcConfigTest, CopiesBitrateForSingleSpatialLayer) {
+TEST(Av1SvcConfigTest, CopiesMinMaxBitrateForSingleSpatialLayer) {
VideoCodec video_codec;
video_codec.codecType = kVideoCodecAV1;
video_codec.SetScalabilityMode("L1T3");
video_codec.minBitrate = 100;
- video_codec.startBitrate = 200;
video_codec.maxBitrate = 500;
EXPECT_TRUE(SetAv1SvcConfig(video_codec));
EXPECT_EQ(video_codec.spatialLayers[0].minBitrate, 100u);
- EXPECT_EQ(video_codec.spatialLayers[0].targetBitrate, 200u);
EXPECT_EQ(video_codec.spatialLayers[0].maxBitrate, 500u);
+ EXPECT_LE(video_codec.spatialLayers[0].minBitrate,
+ video_codec.spatialLayers[0].targetBitrate);
+ EXPECT_LE(video_codec.spatialLayers[0].targetBitrate,
+ video_codec.spatialLayers[0].maxBitrate);
}
TEST(Av1SvcConfigTest, SetsBitratesForMultipleSpatialLayers) {
diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
index 8c82476b7a..3b5fdd78e2 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
@@ -588,12 +588,26 @@ int32_t LibaomAv1Encoder::Encode(
// kNative. As a workaround to this, we perform ToI420() a second time.
// TODO(https://crbug.com/webrtc/12602): When Android buffers have a correct
// ToI420() implementaion, remove his workaround.
+ if (!converted_buffer) {
+ RTC_LOG(LS_ERROR) << "Failed to convert "
+ << VideoFrameBufferTypeToString(
+ converted_buffer->type())
+ << " image to I420. Can't encode frame.";
+ return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE;
+ }
if (converted_buffer->type() != VideoFrameBuffer::Type::kI420 &&
converted_buffer->type() != VideoFrameBuffer::Type::kI420A) {
converted_buffer = converted_buffer->ToI420();
RTC_CHECK(converted_buffer->type() == VideoFrameBuffer::Type::kI420 ||
converted_buffer->type() == VideoFrameBuffer::Type::kI420A);
}
+ if (!converted_buffer) {
+ RTC_LOG(LS_ERROR) << "Failed to convert "
+ << VideoFrameBufferTypeToString(
+ converted_buffer->type())
+ << " image to I420. Can't encode frame.";
+ return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE;
+ }
prepped_input_frame = VideoFrame(converted_buffer, frame.timestamp(),
frame.render_time_ms(), frame.rotation());
}
@@ -671,8 +685,15 @@ int32_t LibaomAv1Encoder::Encode(
encoded_image.content_type_ = VideoContentType::UNSPECIFIED;
// If encoded image width/height info are added to aom_codec_cx_pkt_t,
// use those values in lieu of the values in frame.
- encoded_image._encodedHeight = frame.height();
- encoded_image._encodedWidth = frame.width();
+ if (svc_params_) {
+ int n = svc_params_->scaling_factor_num[layer_frame.SpatialId()];
+ int d = svc_params_->scaling_factor_den[layer_frame.SpatialId()];
+ encoded_image._encodedWidth = cfg_.g_w * n / d;
+ encoded_image._encodedHeight = cfg_.g_h * n / d;
+ } else {
+ encoded_image._encodedWidth = cfg_.g_w;
+ encoded_image._encodedHeight = cfg_.g_h;
+ }
encoded_image.timing_.flags = VideoSendTiming::kInvalid;
int qp = -1;
ret = aom_codec_control(&ctx_, AOME_GET_LAST_QUANTIZER, &qp);
diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc
index ea77e091af..96057a0ce2 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc
@@ -25,6 +25,7 @@ namespace webrtc {
namespace {
using ::testing::ElementsAre;
+using ::testing::Field;
using ::testing::IsEmpty;
using ::testing::SizeIs;
@@ -135,5 +136,36 @@ TEST(LibaomAv1EncoderTest, EncoderInfoProvidesFpsAllocation) {
EXPECT_THAT(encoder_info.fps_allocation[3], IsEmpty());
}
+TEST(LibaomAv1EncoderTest, PopulatesEncodedFrameSize) {
+ std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+ VideoCodec codec_settings = DefaultCodecSettings();
+ ASSERT_GT(codec_settings.width, 4);
+ // Configure encoder with 3 spatial layers.
+ codec_settings.SetScalabilityMode("L3T1");
+ ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
+ WEBRTC_VIDEO_CODEC_OK);
+
+ using Frame = EncodedVideoFrameProducer::EncodedFrame;
+ std::vector<Frame> encoded_frames =
+ EncodedVideoFrameProducer(*encoder).SetNumInputFrames(1).Encode();
+ EXPECT_THAT(
+ encoded_frames,
+ ElementsAre(
+ Field(&Frame::encoded_image,
+ AllOf(Field(&EncodedImage::_encodedWidth,
+ codec_settings.width / 4),
+ Field(&EncodedImage::_encodedHeight,
+ codec_settings.height / 4))),
+ Field(&Frame::encoded_image,
+ AllOf(Field(&EncodedImage::_encodedWidth,
+ codec_settings.width / 2),
+ Field(&EncodedImage::_encodedHeight,
+ codec_settings.height / 2))),
+ Field(&Frame::encoded_image,
+ AllOf(Field(&EncodedImage::_encodedWidth, codec_settings.width),
+ Field(&EncodedImage::_encodedHeight,
+ codec_settings.height)))));
+}
+
} // namespace
} // namespace webrtc