From ef005bc9241513ffc91207b18a449fd495e3dd4f Mon Sep 17 00:00:00 2001 From: philipel Date: Wed, 16 Nov 2022 15:13:24 +0100 Subject: [PATCH] Unwrap the presentation timestamp before calling aom_codec_encode in LibaomAv1Encoder. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:14673 Change-Id: I0358fed5ac0839994482c5fb049c13e442f82c82 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/283701 Reviewed-by: Erik Språng Commit-Queue: Philip Eliasson Cr-Commit-Position: refs/heads/main@{#38657} --- modules/video_coding/codecs/av1/BUILD.gn | 1 + .../codecs/av1/libaom_av1_encoder.cc | 10 +++++--- .../codecs/av1/libaom_av1_encoder_unittest.cc | 25 +++++++++++++++++++ .../test/encoded_video_frame_producer.h | 8 ++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/modules/video_coding/codecs/av1/BUILD.gn b/modules/video_coding/codecs/av1/BUILD.gn index 24be86c0ba..1e23ccb082 100644 --- a/modules/video_coding/codecs/av1/BUILD.gn +++ b/modules/video_coding/codecs/av1/BUILD.gn @@ -61,6 +61,7 @@ rtc_library("libaom_av1_encoder") { "../../../../common_video", "../../../../rtc_base:checks", "../../../../rtc_base:logging", + "../../../../rtc_base:rtc_numerics", "../../svc:scalability_structures", "../../svc:scalable_video_controller", "//third_party/libaom", diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc index 807513bc7b..e5bf4ced90 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc @@ -32,6 +32,7 @@ #include "modules/video_coding/svc/scalable_video_controller_no_layering.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" +#include "rtc_base/numerics/sequence_number_util.h" #include "third_party/libaom/source/libaom/aom/aom_codec.h" #include "third_party/libaom/source/libaom/aom/aom_encoder.h" #include "third_party/libaom/source/libaom/aom/aomcx.h" @@ -117,6 +118,7 @@ class LibaomAv1Encoder final : public VideoEncoder { aom_codec_ctx_t ctx_; aom_codec_enc_cfg_t cfg_; EncodedImageCallback* encoded_image_callback_; + SeqNumUnwrapper rtp_timestamp_unwrapper_; }; int32_t VerifyCodecSettings(const VideoCodec& codec_settings) { @@ -636,9 +638,11 @@ int32_t LibaomAv1Encoder::Encode( layer_frame->TemporalId() > 0 ? 1 : 0); } - // Encode a frame. - aom_codec_err_t ret = aom_codec_encode(&ctx_, frame_for_encode_, - frame.timestamp(), duration, flags); + // Encode a frame. The presentation timestamp `pts` should never wrap, hence + // the unwrapping. + aom_codec_err_t ret = aom_codec_encode( + &ctx_, frame_for_encode_, + rtp_timestamp_unwrapper_.Unwrap(frame.timestamp()), duration, flags); if (ret != AOM_CODEC_OK) { RTC_LOG(LS_WARNING) << "LibaomAv1Encoder::Encode returned " << ret << " on aom_codec_encode."; 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 5243edc1e4..d194cef35b 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc @@ -10,6 +10,7 @@ #include "modules/video_coding/codecs/av1/libaom_av1_encoder.h" +#include #include #include @@ -235,5 +236,29 @@ TEST(LibaomAv1EncoderTest, PopulatesEncodedFrameSize) { codec_settings.height))))); } +TEST(LibaomAv1EncoderTest, RtpTimestampWrap) { + std::unique_ptr encoder = CreateLibaomAv1Encoder(); + VideoCodec codec_settings = DefaultCodecSettings(); + codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1); + ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()), + WEBRTC_VIDEO_CODEC_OK); + + VideoEncoder::RateControlParameters rate_parameters; + rate_parameters.framerate_fps = 30; + rate_parameters.bitrate.SetBitrate(/*spatial_index=*/0, 0, 300'000); + encoder->SetRates(rate_parameters); + + std::vector encoded_frames = + EncodedVideoFrameProducer(*encoder) + .SetNumInputFrames(2) + .SetRtpTimestamp(std::numeric_limits::max()) + .Encode(); + ASSERT_THAT(encoded_frames, SizeIs(2)); + EXPECT_THAT(encoded_frames[0].encoded_image._frameType, + Eq(VideoFrameType::kVideoFrameKey)); + EXPECT_THAT(encoded_frames[1].encoded_image._frameType, + Eq(VideoFrameType::kVideoFrameDelta)); +} + } // namespace } // namespace webrtc diff --git a/modules/video_coding/codecs/test/encoded_video_frame_producer.h b/modules/video_coding/codecs/test/encoded_video_frame_producer.h index 2216287b92..04f4a64950 100644 --- a/modules/video_coding/codecs/test/encoded_video_frame_producer.h +++ b/modules/video_coding/codecs/test/encoded_video_frame_producer.h @@ -47,6 +47,8 @@ class EncodedVideoFrameProducer { EncodedVideoFrameProducer& SetFramerateFps(int value); + EncodedVideoFrameProducer& SetRtpTimestamp(uint32_t value); + // Generates input video frames and encodes them with `encoder` provided in // the constructor. Returns frame passed to the `OnEncodedImage` by wraping // `EncodedImageCallback` underneath. @@ -88,5 +90,11 @@ inline EncodedVideoFrameProducer& EncodedVideoFrameProducer::SetFramerateFps( return *this; } +inline EncodedVideoFrameProducer& EncodedVideoFrameProducer::SetRtpTimestamp( + uint32_t value) { + rtp_timestamp_ = value; + return *this; +} + } // namespace webrtc #endif // MODULES_VIDEO_CODING_CODECS_TEST_ENCODED_VIDEO_FRAME_PRODUCER_H_