blob: a2fa8cc2862dfd515334e2a9e844eea04c0527b3 [file] [log] [blame]
/*
* Copyright (c) 2025 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "video/timing/simulator/test/encoded_frame_generators.h"
#include <cstdint>
#include <memory>
#include "api/environment/environment.h"
#include "api/rtp_packet_info.h"
#include "api/rtp_packet_infos.h"
#include "api/units/timestamp.h"
#include "api/video/encoded_frame.h"
#include "rtc_base/checks.h"
#include "test/fake_encoded_frame.h"
namespace webrtc::video_timing_simulator {
namespace {
constexpr int kFrameSizeBytes = 2000;
constexpr int kPayloadType = 96;
} // namespace
EncodedFrameBuilderGenerator::EncodedFrameBuilderGenerator(
const Environment& env)
: env_(env) {}
EncodedFrameBuilderGenerator::~EncodedFrameBuilderGenerator() = default;
EncodedFrameBuilderGenerator::BuilderWithFrameId
EncodedFrameBuilderGenerator::NextEncodedFrameBuilder() {
test::FakeFrameBuilder builder;
Timestamp now = env_.clock().CurrentTime();
builder = builder.Time(rtp_timestamp_)
.Id(frame_id_)
.AsLast()
.SpatialLayer(0)
.ReceivedTime(now)
.Size(kFrameSizeBytes)
.PayloadType(kPayloadType)
.PacketInfos(RtpPacketInfos(
{RtpPacketInfo(kSsrc, /*csrcs=*/{}, rtp_timestamp_, now)}));
BuilderWithFrameId ret = {.builder = builder, .frame_id = frame_id_};
// 30 fps.
rtp_timestamp_ += 3000;
++frame_id_;
return ret;
}
SingleLayerEncodedFrameGenerator::SingleLayerEncodedFrameGenerator(
const Environment& env)
: builder_generator_(env) {}
SingleLayerEncodedFrameGenerator::~SingleLayerEncodedFrameGenerator() = default;
std::unique_ptr<EncodedFrame>
SingleLayerEncodedFrameGenerator::NextEncodedFrame() {
EncodedFrameBuilderGenerator::BuilderWithFrameId builder_and_frame_id =
builder_generator_.NextEncodedFrameBuilder();
if (builder_and_frame_id.frame_id == 0) {
// Keyframe.
return builder_and_frame_id.builder.Build();
}
return builder_and_frame_id.builder.Refs({builder_and_frame_id.frame_id - 1})
.Build();
}
TemporalLayersEncodedFrameGenerator::TemporalLayersEncodedFrameGenerator(
const Environment& env)
: builder_generator_(env) {}
TemporalLayersEncodedFrameGenerator::~TemporalLayersEncodedFrameGenerator() =
default;
std::unique_ptr<EncodedFrame>
TemporalLayersEncodedFrameGenerator::NextEncodedFrame() {
EncodedFrameBuilderGenerator::BuilderWithFrameId builder_and_frame_id =
builder_generator_.NextEncodedFrameBuilder();
int64_t frame_id = builder_and_frame_id.frame_id;
if (frame_id == 0) {
// Keyframe.
return builder_and_frame_id.builder.Build();
}
test::FakeFrameBuilder builder = builder_and_frame_id.builder;
int64_t mod = frame_id % kNumTemporalLayers;
if (mod == 0) {
// The keyframe is handled above.
RTC_CHECK_GE(frame_id, 4);
return builder.Refs({frame_id - 4}).Build();
} else if (mod == 1) {
RTC_CHECK_GE(frame_id, 1);
return builder.Refs({frame_id - 1}).Build();
} else if (mod == 2) {
RTC_CHECK_GE(frame_id, 2);
return builder.Refs({frame_id - 2}).Build();
} else if (mod == 3) {
RTC_CHECK_GE(frame_id, 3);
return builder.Refs({frame_id - 1}).Build();
}
RTC_CHECK_NOTREACHED();
return test::FakeFrameBuilder().Build();
}
} // namespace webrtc::video_timing_simulator