mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 13:50:40 +01:00
Rename "UpdateLayerConfig" to "NextFrameConfig"
Rename "UpdateLayerConfig" to the more appropriate "NextFrameConfig". Also update some comments in vp8_frame_buffer_controller.h. Bug: None Change-Id: Iba8227f84e33e5ebd28d2eeb10fe03e776036603 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/133202 Commit-Queue: Elad Alon <eladalon@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27660}
This commit is contained in:
parent
123ee9be8f
commit
979c4426a4
12 changed files with 94 additions and 91 deletions
|
@ -25,7 +25,7 @@ namespace webrtc {
|
||||||
// * Vp8FrameBufferController is not thread safe, synchronization is the
|
// * Vp8FrameBufferController is not thread safe, synchronization is the
|
||||||
// caller's responsibility.
|
// caller's responsibility.
|
||||||
// * The encoder is assumed to encode all frames in order, and callbacks to
|
// * The encoder is assumed to encode all frames in order, and callbacks to
|
||||||
// PopulateCodecSpecific() / FrameEncoded() must happen in the same order.
|
// PopulateCodecSpecific() / OnEncodeDone() must happen in the same order.
|
||||||
//
|
//
|
||||||
// This means that in the case of pipelining encoders, it is OK to have a chain
|
// This means that in the case of pipelining encoders, it is OK to have a chain
|
||||||
// of calls such as this:
|
// of calls such as this:
|
||||||
|
@ -38,11 +38,15 @@ namespace webrtc {
|
||||||
// - OnEncodeDone(timestampB, 0, ...)
|
// - OnEncodeDone(timestampB, 0, ...)
|
||||||
// - OnEncodeDone(timestampC, 1234, ...)
|
// - OnEncodeDone(timestampC, 1234, ...)
|
||||||
// Note that UpdateLayerConfig() for a new frame can happen before
|
// Note that UpdateLayerConfig() for a new frame can happen before
|
||||||
// FrameEncoded() for a previous one, but calls themselves must be both
|
// OnEncodeDone() for a previous one, but calls themselves must be both
|
||||||
// synchronized (e.g. run on a task queue) and in order (per type).
|
// synchronized (e.g. run on a task queue) and in order (per type).
|
||||||
|
//
|
||||||
|
// TODO(eladalon): Revise comment (referring to PopulateCodecSpecific in this
|
||||||
|
// context is not very meaningful).
|
||||||
|
|
||||||
struct CodecSpecificInfo;
|
struct CodecSpecificInfo;
|
||||||
|
|
||||||
|
// TODO(eladalon): This configuration is temporal-layers specific; refactor.
|
||||||
struct Vp8EncoderConfig {
|
struct Vp8EncoderConfig {
|
||||||
static constexpr size_t kMaxPeriodicity = 16;
|
static constexpr size_t kMaxPeriodicity = 16;
|
||||||
static constexpr size_t kMaxLayers = 5;
|
static constexpr size_t kMaxLayers = 5;
|
||||||
|
@ -90,37 +94,36 @@ class Vp8FrameBufferController {
|
||||||
// OnEncodeDone() again when the frame has actually been encoded.
|
// OnEncodeDone() again when the frame has actually been encoded.
|
||||||
virtual bool SupportsEncoderFrameDropping(size_t stream_index) const = 0;
|
virtual bool SupportsEncoderFrameDropping(size_t stream_index) const = 0;
|
||||||
|
|
||||||
// New target bitrate, per temporal layer.
|
// New target bitrate for a stream (each entry in
|
||||||
|
// |bitrates_bps| is for another temporal layer).
|
||||||
virtual void OnRatesUpdated(size_t stream_index,
|
virtual void OnRatesUpdated(size_t stream_index,
|
||||||
const std::vector<uint32_t>& bitrates_bps,
|
const std::vector<uint32_t>& bitrates_bps,
|
||||||
int framerate_fps) = 0;
|
int framerate_fps) = 0;
|
||||||
|
|
||||||
// Called by the encoder before encoding a frame. |cfg| contains the current
|
// Called by the encoder before encoding a frame. |cfg| contains the current
|
||||||
// configuration. If the TemporalLayers instance wishes any part of that
|
// configuration. If the encoder wishes any part of that to be changed before
|
||||||
// to be changed before the encode step, |cfg| should be changed and then
|
// the encode step, |cfg| should be changed and then return true. If false is
|
||||||
// return true. If false is returned, the encoder will proceed without
|
// returned, the encoder will proceed without updating the configuration.
|
||||||
// updating the configuration.
|
|
||||||
virtual bool UpdateConfiguration(size_t stream_index,
|
virtual bool UpdateConfiguration(size_t stream_index,
|
||||||
Vp8EncoderConfig* cfg) = 0;
|
Vp8EncoderConfig* cfg) = 0;
|
||||||
|
|
||||||
// Returns the recommended VP8 encode flags needed, and moves the temporal
|
// Returns the recommended VP8 encode flags needed.
|
||||||
// pattern to the next frame.
|
|
||||||
// The timestamp may be used as both a time and a unique identifier, and so
|
// The timestamp may be used as both a time and a unique identifier, and so
|
||||||
// the caller must make sure no two frames use the same timestamp.
|
// the caller must make sure no two frames use the same timestamp.
|
||||||
// The timestamp uses a 90kHz RTP clock.
|
// The timestamp uses a 90kHz RTP clock.
|
||||||
// After calling this method, first call the actual encoder with the provided
|
// After calling this method, first call the actual encoder with the provided
|
||||||
// frame configuration, and then OnEncodeDone() below.
|
// frame configuration, and then OnEncodeDone() below.
|
||||||
virtual Vp8FrameConfig UpdateLayerConfig(size_t stream_index,
|
virtual Vp8FrameConfig NextFrameConfig(size_t stream_index,
|
||||||
uint32_t rtp_timestamp) = 0;
|
uint32_t rtp_timestamp) = 0;
|
||||||
|
|
||||||
// Called after the encode step is done. |rtp_timestamp| must match the
|
// Called after the encode step is done. |rtp_timestamp| must match the
|
||||||
// parameter use in the UpdateLayerConfig() call.
|
// parameter use in the UpdateLayerConfig() call.
|
||||||
// |is_keyframe| must be true iff the encoder decided to encode this frame as
|
// |is_keyframe| must be true iff the encoder decided to encode this frame as
|
||||||
// a keyframe.
|
// a keyframe.
|
||||||
// If |info| is not null, the TemporalLayers instance may update |info| with
|
// If |info| is not null, the encoder may update |info| with codec specific
|
||||||
// codec specific data such as temporal id.
|
// data such as temporal id. |qp| should indicate the frame-level QP this
|
||||||
// |qp| should indicate the frame-level QP this frame was encoded at. If the
|
// frame was encoded at. If the encoder does not support extracting this, |qp|
|
||||||
// encoder does not support extracting this, |qp| should be set to 0.
|
// should be set to 0.
|
||||||
virtual void OnEncodeDone(size_t stream_index,
|
virtual void OnEncodeDone(size_t stream_index,
|
||||||
uint32_t rtp_timestamp,
|
uint32_t rtp_timestamp,
|
||||||
size_t size_bytes,
|
size_t size_bytes,
|
||||||
|
|
|
@ -53,10 +53,10 @@ bool Vp8TemporalLayers::UpdateConfiguration(size_t stream_index,
|
||||||
return controllers_[stream_index]->UpdateConfiguration(0, cfg);
|
return controllers_[stream_index]->UpdateConfiguration(0, cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vp8FrameConfig Vp8TemporalLayers::UpdateLayerConfig(size_t stream_index,
|
Vp8FrameConfig Vp8TemporalLayers::NextFrameConfig(size_t stream_index,
|
||||||
uint32_t rtp_timestamp) {
|
uint32_t rtp_timestamp) {
|
||||||
RTC_DCHECK_LT(stream_index, controllers_.size());
|
RTC_DCHECK_LT(stream_index, controllers_.size());
|
||||||
return controllers_[stream_index]->UpdateLayerConfig(0, rtp_timestamp);
|
return controllers_[stream_index]->NextFrameConfig(0, rtp_timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vp8TemporalLayers::OnEncodeDone(size_t stream_index,
|
void Vp8TemporalLayers::OnEncodeDone(size_t stream_index,
|
||||||
|
|
|
@ -45,7 +45,7 @@ class Vp8TemporalLayers final : public Vp8FrameBufferController {
|
||||||
|
|
||||||
bool UpdateConfiguration(size_t stream_index, Vp8EncoderConfig* cfg) override;
|
bool UpdateConfiguration(size_t stream_index, Vp8EncoderConfig* cfg) override;
|
||||||
|
|
||||||
Vp8FrameConfig UpdateLayerConfig(size_t stream_index,
|
Vp8FrameConfig NextFrameConfig(size_t stream_index,
|
||||||
uint32_t rtp_timestamp) override;
|
uint32_t rtp_timestamp) override;
|
||||||
|
|
||||||
void OnEncodeDone(size_t stream_index,
|
void OnEncodeDone(size_t stream_index,
|
||||||
|
|
|
@ -330,7 +330,7 @@ bool DefaultTemporalLayers::IsSyncFrame(const Vp8FrameConfig& config) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vp8FrameConfig DefaultTemporalLayers::UpdateLayerConfig(size_t stream_index,
|
Vp8FrameConfig DefaultTemporalLayers::NextFrameConfig(size_t stream_index,
|
||||||
uint32_t timestamp) {
|
uint32_t timestamp) {
|
||||||
RTC_DCHECK_LT(stream_index, StreamCount());
|
RTC_DCHECK_LT(stream_index, StreamCount());
|
||||||
RTC_DCHECK_GT(num_layers_, 0);
|
RTC_DCHECK_GT(num_layers_, 0);
|
||||||
|
|
|
@ -40,7 +40,7 @@ class DefaultTemporalLayers final : public Vp8FrameBufferController {
|
||||||
|
|
||||||
// Returns the recommended VP8 encode flags needed. May refresh the decoder
|
// Returns the recommended VP8 encode flags needed. May refresh the decoder
|
||||||
// and/or update the reference buffers.
|
// and/or update the reference buffers.
|
||||||
Vp8FrameConfig UpdateLayerConfig(size_t stream_index,
|
Vp8FrameConfig NextFrameConfig(size_t stream_index,
|
||||||
uint32_t timestamp) override;
|
uint32_t timestamp) override;
|
||||||
|
|
||||||
// New target bitrate, per temporal layer.
|
// New target bitrate, per temporal layer.
|
||||||
|
@ -108,7 +108,7 @@ class DefaultTemporalLayers final : public Vp8FrameBufferController {
|
||||||
// Bitmask of Vp8BufferReference flags, indicating which buffers this frame
|
// Bitmask of Vp8BufferReference flags, indicating which buffers this frame
|
||||||
// updates.
|
// updates.
|
||||||
uint8_t updated_buffer_mask = 0;
|
uint8_t updated_buffer_mask = 0;
|
||||||
// The frame config return by UpdateLayerConfig() for this frame.
|
// The frame config returned by NextFrameConfig() for this frame.
|
||||||
DependencyInfo dependency_info;
|
DependencyInfo dependency_info;
|
||||||
};
|
};
|
||||||
// Map from rtp timestamp to pending frame status. Reset on pattern loop.
|
// Map from rtp timestamp to pending frame status. Reset on pattern loop.
|
||||||
|
|
|
@ -142,7 +142,7 @@ TEST_F(TemporalLayersTest, 2Layers) {
|
||||||
for (size_t i = 0; i < kPatternSize * kRepetitions; ++i) {
|
for (size_t i = 0; i < kPatternSize * kRepetitions; ++i) {
|
||||||
const size_t ind = i % kPatternSize;
|
const size_t ind = i % kPatternSize;
|
||||||
CodecSpecificInfo info;
|
CodecSpecificInfo info;
|
||||||
Vp8FrameConfig tl_config = tl.UpdateLayerConfig(0, timestamp);
|
Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
|
||||||
EXPECT_EQ(expected_flags[ind], LibvpxVp8Encoder::EncodeFlags(tl_config))
|
EXPECT_EQ(expected_flags[ind], LibvpxVp8Encoder::EncodeFlags(tl_config))
|
||||||
<< i;
|
<< i;
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
||||||
|
@ -197,7 +197,7 @@ TEST_F(TemporalLayersTest, 3Layers) {
|
||||||
unsigned int timestamp = 0;
|
unsigned int timestamp = 0;
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < 16; ++i) {
|
||||||
CodecSpecificInfo info;
|
CodecSpecificInfo info;
|
||||||
Vp8FrameConfig tl_config = tl.UpdateLayerConfig(0, timestamp);
|
Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
|
||||||
EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
|
EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
||||||
&info);
|
&info);
|
||||||
|
@ -240,7 +240,7 @@ TEST_F(TemporalLayersTest, Alternative3Layers) {
|
||||||
unsigned int timestamp = 0;
|
unsigned int timestamp = 0;
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
CodecSpecificInfo info;
|
CodecSpecificInfo info;
|
||||||
Vp8FrameConfig tl_config = tl.UpdateLayerConfig(0, timestamp);
|
Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
|
||||||
EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
|
EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
||||||
&info);
|
&info);
|
||||||
|
@ -272,19 +272,19 @@ TEST_F(TemporalLayersTest, SearchOrder) {
|
||||||
|
|
||||||
// Start with a key-frame. tl_config flags can be ignored.
|
// Start with a key-frame. tl_config flags can be ignored.
|
||||||
uint32_t timestamp = 0;
|
uint32_t timestamp = 0;
|
||||||
Vp8FrameConfig tl_config = tl.UpdateLayerConfig(0, timestamp);
|
Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// TL2 frame. First one only references TL0. Updates altref.
|
// TL2 frame. First one only references TL0. Updates altref.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kLast);
|
EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kLast);
|
||||||
EXPECT_EQ(tl_config.second_reference, Vp8BufferReference::kNone);
|
EXPECT_EQ(tl_config.second_reference, Vp8BufferReference::kNone);
|
||||||
|
|
||||||
// TL1 frame. Can only reference TL0. Updated golden.
|
// TL1 frame. Can only reference TL0. Updated golden.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kLast);
|
EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kLast);
|
||||||
|
@ -292,7 +292,7 @@ TEST_F(TemporalLayersTest, SearchOrder) {
|
||||||
|
|
||||||
// TL2 frame. Can reference all three buffers. Golden was the last to be
|
// TL2 frame. Can reference all three buffers. Golden was the last to be
|
||||||
// updated, the next to last was altref.
|
// updated, the next to last was altref.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kGolden);
|
EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kGolden);
|
||||||
|
@ -316,24 +316,24 @@ TEST_F(TemporalLayersTest, SearchOrderWithDrop) {
|
||||||
|
|
||||||
// Start with a key-frame. tl_config flags can be ignored.
|
// Start with a key-frame. tl_config flags can be ignored.
|
||||||
uint32_t timestamp = 0;
|
uint32_t timestamp = 0;
|
||||||
Vp8FrameConfig tl_config = tl.UpdateLayerConfig(0, timestamp);
|
Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// TL2 frame. First one only references TL0. Updates altref.
|
// TL2 frame. First one only references TL0. Updates altref.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kLast);
|
EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kLast);
|
||||||
EXPECT_EQ(tl_config.second_reference, Vp8BufferReference::kNone);
|
EXPECT_EQ(tl_config.second_reference, Vp8BufferReference::kNone);
|
||||||
|
|
||||||
// Dropped TL1 frame. Can only reference TL0. Should have updated golden.
|
// Dropped TL1 frame. Can only reference TL0. Should have updated golden.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);
|
tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);
|
||||||
|
|
||||||
// TL2 frame. Can normally reference all three buffers, but golden has not
|
// TL2 frame. Can normally reference all three buffers, but golden has not
|
||||||
// been populated this cycle. Altref was last to be updated, before that last.
|
// been populated this cycle. Altref was last to be updated, before that last.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kAltref);
|
EXPECT_EQ(tl_config.first_reference, Vp8BufferReference::kAltref);
|
||||||
|
@ -378,7 +378,7 @@ TEST_F(TemporalLayersTest, 4Layers) {
|
||||||
uint32_t timestamp = 0;
|
uint32_t timestamp = 0;
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < 16; ++i) {
|
||||||
CodecSpecificInfo info;
|
CodecSpecificInfo info;
|
||||||
Vp8FrameConfig tl_config = tl.UpdateLayerConfig(0, timestamp);
|
Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
|
||||||
EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
|
EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
||||||
&info);
|
&info);
|
||||||
|
@ -409,21 +409,21 @@ TEST_F(TemporalLayersTest, DoesNotReferenceDroppedFrames) {
|
||||||
|
|
||||||
// Start with a keyframe.
|
// Start with a keyframe.
|
||||||
uint32_t timestamp = 0;
|
uint32_t timestamp = 0;
|
||||||
Vp8FrameConfig tl_config = tl.UpdateLayerConfig(0, timestamp);
|
Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// Dropped TL2 frame.
|
// Dropped TL2 frame.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);
|
tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);
|
||||||
|
|
||||||
// Dropped TL1 frame.
|
// Dropped TL1 frame.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);
|
tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);
|
||||||
|
|
||||||
// TL2 frame. Can reference all three buffers, valid since golden and altref
|
// TL2 frame. Can reference all three buffers, valid since golden and altref
|
||||||
// both contain the last keyframe.
|
// both contain the last keyframe.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
|
EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
|
||||||
|
@ -433,23 +433,23 @@ TEST_F(TemporalLayersTest, DoesNotReferenceDroppedFrames) {
|
||||||
// Restart of cycle!
|
// Restart of cycle!
|
||||||
|
|
||||||
// TL0 base layer frame, updating and referencing last.
|
// TL0 base layer frame, updating and referencing last.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// TL2 frame, updating altref.
|
// TL2 frame, updating altref.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// TL1 frame, updating golden.
|
// TL1 frame, updating golden.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// TL2 frame. Can still reference all buffer since they have been update this
|
// TL2 frame. Can still reference all buffer since they have been update this
|
||||||
// cycle.
|
// cycle.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
|
EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
|
||||||
|
@ -459,21 +459,21 @@ TEST_F(TemporalLayersTest, DoesNotReferenceDroppedFrames) {
|
||||||
// Restart of cycle!
|
// Restart of cycle!
|
||||||
|
|
||||||
// TL0 base layer frame, updating and referencing last.
|
// TL0 base layer frame, updating and referencing last.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// Dropped TL2 frame.
|
// Dropped TL2 frame.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);
|
tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);
|
||||||
|
|
||||||
// Dropped TL1 frame.
|
// Dropped TL1 frame.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);
|
tl.OnEncodeDone(0, timestamp, 0, false, 0, nullptr);
|
||||||
|
|
||||||
// TL2 frame. This time golden and altref contain data from the previous cycle
|
// TL2 frame. This time golden and altref contain data from the previous cycle
|
||||||
// and cannot be referenced.
|
// and cannot be referenced.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
|
EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
|
||||||
|
@ -496,40 +496,40 @@ TEST_F(TemporalLayersTest, DoesNotReferenceUnlessGuaranteedToExist) {
|
||||||
|
|
||||||
// Start with a keyframe.
|
// Start with a keyframe.
|
||||||
uint32_t timestamp = 0;
|
uint32_t timestamp = 0;
|
||||||
Vp8FrameConfig tl_config = tl.UpdateLayerConfig(0, timestamp);
|
Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// Do a full cycle of the pattern.
|
// Do a full cycle of the pattern.
|
||||||
for (int i = 0; i < 7; ++i) {
|
for (int i = 0; i < 7; ++i) {
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TL0 base layer frame, starting the cycle over.
|
// TL0 base layer frame, starting the cycle over.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// TL2 frame.
|
// TL2 frame.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// Encoder has a hiccup and builds a queue, so frame encoding is delayed.
|
// Encoder has a hiccup and builds a queue, so frame encoding is delayed.
|
||||||
// TL1 frame, updating golden.
|
// TL1 frame, updating golden.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
|
|
||||||
// TL2 frame, that should be referencing golden, but we can't be certain it's
|
// TL2 frame, that should be referencing golden, but we can't be certain it's
|
||||||
// not going to be dropped, so that is not allowed.
|
// not going to be dropped, so that is not allowed.
|
||||||
tl_config = tl.UpdateLayerConfig(0, timestamp + 1);
|
tl_config = tl.NextFrameConfig(0, timestamp + 1);
|
||||||
EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
|
EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
|
||||||
EXPECT_FALSE(tl_config.golden_buffer_flags & BufferFlags::kReference);
|
EXPECT_FALSE(tl_config.golden_buffer_flags & BufferFlags::kReference);
|
||||||
EXPECT_FALSE(tl_config.arf_buffer_flags & BufferFlags::kReference);
|
EXPECT_FALSE(tl_config.arf_buffer_flags & BufferFlags::kReference);
|
||||||
|
|
||||||
// TL0 base layer frame.
|
// TL0 base layer frame.
|
||||||
tl_config = tl.UpdateLayerConfig(0, timestamp + 2);
|
tl_config = tl.NextFrameConfig(0, timestamp + 2);
|
||||||
|
|
||||||
// The previous four enqueued frames finally get encoded, and the updated
|
// The previous four enqueued frames finally get encoded, and the updated
|
||||||
// buffers are now OK to reference.
|
// buffers are now OK to reference.
|
||||||
|
@ -544,7 +544,7 @@ TEST_F(TemporalLayersTest, DoesNotReferenceUnlessGuaranteedToExist) {
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// TL2 frame, all buffers are now in a known good state, OK to reference.
|
// TL2 frame, all buffers are now in a known good state, OK to reference.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp + 1);
|
tl_config = tl.NextFrameConfig(0, ++timestamp + 1);
|
||||||
EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
|
EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
|
||||||
EXPECT_TRUE(tl_config.golden_buffer_flags & BufferFlags::kReference);
|
EXPECT_TRUE(tl_config.golden_buffer_flags & BufferFlags::kReference);
|
||||||
EXPECT_FALSE(tl_config.arf_buffer_flags & BufferFlags::kReference);
|
EXPECT_FALSE(tl_config.arf_buffer_flags & BufferFlags::kReference);
|
||||||
|
@ -566,37 +566,37 @@ TEST_F(TemporalLayersTest, DoesNotReferenceUnlessGuaranteedToExistLongDelay) {
|
||||||
|
|
||||||
// Start with a keyframe.
|
// Start with a keyframe.
|
||||||
uint32_t timestamp = 0;
|
uint32_t timestamp = 0;
|
||||||
Vp8FrameConfig tl_config = tl.UpdateLayerConfig(0, timestamp);
|
Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// Do a full cycle of the pattern.
|
// Do a full cycle of the pattern.
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TL0 base layer frame, starting the cycle over.
|
// TL0 base layer frame, starting the cycle over.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// TL2 frame.
|
// TL2 frame.
|
||||||
tl_config = tl.UpdateLayerConfig(0, ++timestamp);
|
tl_config = tl.NextFrameConfig(0, ++timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
// Encoder has a hiccup and builds a queue, so frame encoding is delayed.
|
// Encoder has a hiccup and builds a queue, so frame encoding is delayed.
|
||||||
// Encoded, but delayed frames in TL 1, 2.
|
// Encoded, but delayed frames in TL 1, 2.
|
||||||
tl_config = tl.UpdateLayerConfig(0, timestamp + 1);
|
tl_config = tl.NextFrameConfig(0, timestamp + 1);
|
||||||
tl_config = tl.UpdateLayerConfig(0, timestamp + 2);
|
tl_config = tl.NextFrameConfig(0, timestamp + 2);
|
||||||
|
|
||||||
// Restart of the pattern!
|
// Restart of the pattern!
|
||||||
|
|
||||||
// Encoded, but delayed frames in TL 2, 1.
|
// Encoded, but delayed frames in TL 2, 1.
|
||||||
tl_config = tl.UpdateLayerConfig(0, timestamp + 3);
|
tl_config = tl.NextFrameConfig(0, timestamp + 3);
|
||||||
tl_config = tl.UpdateLayerConfig(0, timestamp + 4);
|
tl_config = tl.NextFrameConfig(0, timestamp + 4);
|
||||||
|
|
||||||
// TL1 frame from last cycle is ready.
|
// TL1 frame from last cycle is ready.
|
||||||
tl.OnEncodeDone(0, timestamp + 1, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp + 1, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
|
@ -608,7 +608,7 @@ TEST_F(TemporalLayersTest, DoesNotReferenceUnlessGuaranteedToExistLongDelay) {
|
||||||
// TL2 frame, that should be referencing all buffers, but altref and golden
|
// TL2 frame, that should be referencing all buffers, but altref and golden
|
||||||
// haven not been updated this cycle. (Don't be fooled by the late frames from
|
// haven not been updated this cycle. (Don't be fooled by the late frames from
|
||||||
// the last cycle!)
|
// the last cycle!)
|
||||||
tl_config = tl.UpdateLayerConfig(0, timestamp + 5);
|
tl_config = tl.NextFrameConfig(0, timestamp + 5);
|
||||||
EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
|
EXPECT_TRUE(tl_config.last_buffer_flags & BufferFlags::kReference);
|
||||||
EXPECT_FALSE(tl_config.golden_buffer_flags & BufferFlags::kReference);
|
EXPECT_FALSE(tl_config.golden_buffer_flags & BufferFlags::kReference);
|
||||||
EXPECT_FALSE(tl_config.arf_buffer_flags & BufferFlags::kReference);
|
EXPECT_FALSE(tl_config.arf_buffer_flags & BufferFlags::kReference);
|
||||||
|
@ -646,7 +646,7 @@ TEST_F(TemporalLayersTest, KeyFrame) {
|
||||||
for (int j = 1; j <= i; ++j) {
|
for (int j = 1; j <= i; ++j) {
|
||||||
// Since last frame was always a keyframe and thus index 0 in the pattern,
|
// Since last frame was always a keyframe and thus index 0 in the pattern,
|
||||||
// this loop starts at index 1.
|
// this loop starts at index 1.
|
||||||
Vp8FrameConfig tl_config = tl.UpdateLayerConfig(0, timestamp);
|
Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
|
||||||
EXPECT_EQ(expected_flags[j], LibvpxVp8Encoder::EncodeFlags(tl_config))
|
EXPECT_EQ(expected_flags[j], LibvpxVp8Encoder::EncodeFlags(tl_config))
|
||||||
<< j;
|
<< j;
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||||
|
@ -659,7 +659,7 @@ TEST_F(TemporalLayersTest, KeyFrame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CodecSpecificInfo info;
|
CodecSpecificInfo info;
|
||||||
Vp8FrameConfig tl_config = tl.UpdateLayerConfig(0, timestamp);
|
Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp);
|
||||||
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
||||||
&info);
|
&info);
|
||||||
EXPECT_TRUE(info.codecSpecific.VP8.layerSync)
|
EXPECT_TRUE(info.codecSpecific.VP8.layerSync)
|
||||||
|
@ -748,7 +748,7 @@ TEST_P(TemporalLayersReferenceTest, ValidFrameConfigs) {
|
||||||
// updates |last|.
|
// updates |last|.
|
||||||
std::vector<Vp8FrameConfig> tl_configs(kMaxPatternLength);
|
std::vector<Vp8FrameConfig> tl_configs(kMaxPatternLength);
|
||||||
for (int i = 0; i < kMaxPatternLength; ++i) {
|
for (int i = 0; i < kMaxPatternLength; ++i) {
|
||||||
Vp8FrameConfig tl_config = tl.UpdateLayerConfig(0, timestamp_);
|
Vp8FrameConfig tl_config = tl.NextFrameConfig(0, timestamp_);
|
||||||
tl.OnEncodeDone(0, timestamp_, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
tl.OnEncodeDone(0, timestamp_, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
++timestamp_;
|
++timestamp_;
|
||||||
|
|
|
@ -923,7 +923,7 @@ int LibvpxVp8Encoder::Encode(const VideoFrame& frame,
|
||||||
Vp8FrameConfig tl_configs[kMaxSimulcastStreams];
|
Vp8FrameConfig tl_configs[kMaxSimulcastStreams];
|
||||||
for (size_t i = 0; i < encoders_.size(); ++i) {
|
for (size_t i = 0; i < encoders_.size(); ++i) {
|
||||||
tl_configs[i] =
|
tl_configs[i] =
|
||||||
frame_buffer_controller_->UpdateLayerConfig(i, frame.timestamp());
|
frame_buffer_controller_->NextFrameConfig(i, frame.timestamp());
|
||||||
if (tl_configs[i].drop_frame) {
|
if (tl_configs[i].drop_frame) {
|
||||||
if (send_key_frame) {
|
if (send_key_frame) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -82,7 +82,7 @@ bool ScreenshareLayers::SupportsEncoderFrameDropping(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vp8FrameConfig ScreenshareLayers::UpdateLayerConfig(size_t stream_index,
|
Vp8FrameConfig ScreenshareLayers::NextFrameConfig(size_t stream_index,
|
||||||
uint32_t timestamp) {
|
uint32_t timestamp) {
|
||||||
RTC_DCHECK_LT(stream_index, StreamCount());
|
RTC_DCHECK_LT(stream_index, StreamCount());
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ class ScreenshareLayers final : public Vp8FrameBufferController {
|
||||||
|
|
||||||
// Returns the recommended VP8 encode flags needed. May refresh the decoder
|
// Returns the recommended VP8 encode flags needed. May refresh the decoder
|
||||||
// and/or update the reference buffers.
|
// and/or update the reference buffers.
|
||||||
Vp8FrameConfig UpdateLayerConfig(size_t stream_index,
|
Vp8FrameConfig NextFrameConfig(size_t stream_index,
|
||||||
uint32_t rtp_timestamp) override;
|
uint32_t rtp_timestamp) override;
|
||||||
|
|
||||||
// New target bitrate, per temporal layer.
|
// New target bitrate, per temporal layer.
|
||||||
|
|
|
@ -85,7 +85,7 @@ class ScreenshareLayerTest : public ::testing::Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ConfigureFrame(bool key_frame) {
|
int ConfigureFrame(bool key_frame) {
|
||||||
tl_config_ = UpdateLayerConfig(0, timestamp_);
|
tl_config_ = NextFrameConfig(0, timestamp_);
|
||||||
EXPECT_EQ(0, tl_config_.encoder_layer_id)
|
EXPECT_EQ(0, tl_config_.encoder_layer_id)
|
||||||
<< "ScreenshareLayers always encodes using the bitrate allocator for "
|
<< "ScreenshareLayers always encodes using the bitrate allocator for "
|
||||||
"layer 0, but may reference different buffers and packetize "
|
"layer 0, but may reference different buffers and packetize "
|
||||||
|
@ -99,10 +99,10 @@ class ScreenshareLayerTest : public ::testing::Test {
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vp8FrameConfig UpdateLayerConfig(size_t stream_index, uint32_t timestamp) {
|
Vp8FrameConfig NextFrameConfig(size_t stream_index, uint32_t timestamp) {
|
||||||
int64_t timestamp_ms = timestamp / 90;
|
int64_t timestamp_ms = timestamp / 90;
|
||||||
clock_.AdvanceTime(TimeDelta::ms(timestamp_ms - rtc::TimeMillis()));
|
clock_.AdvanceTime(TimeDelta::ms(timestamp_ms - rtc::TimeMillis()));
|
||||||
return layers_->UpdateLayerConfig(stream_index, timestamp);
|
return layers_->NextFrameConfig(stream_index, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FrameSizeForBitrate(int bitrate_kbps) {
|
int FrameSizeForBitrate(int bitrate_kbps) {
|
||||||
|
@ -245,7 +245,7 @@ TEST_F(ScreenshareLayerTest, 2LayersSyncAfterTimeout) {
|
||||||
for (int i = 0; i < kNumFrames; ++i) {
|
for (int i = 0; i < kNumFrames; ++i) {
|
||||||
CodecSpecificInfo info;
|
CodecSpecificInfo info;
|
||||||
|
|
||||||
tl_config_ = UpdateLayerConfig(0, timestamp_);
|
tl_config_ = NextFrameConfig(0, timestamp_);
|
||||||
config_updated_ = layers_->UpdateConfiguration(0, &cfg_);
|
config_updated_ = layers_->UpdateConfiguration(0, &cfg_);
|
||||||
|
|
||||||
// Simulate TL1 being at least 8 qp steps better.
|
// Simulate TL1 being at least 8 qp steps better.
|
||||||
|
@ -486,8 +486,8 @@ TEST_F(ScreenshareLayerTest, RespectsMaxIntervalBetweenFrames) {
|
||||||
layers_->OnRatesUpdated(0, layer_rates, kFrameRate);
|
layers_->OnRatesUpdated(0, layer_rates, kFrameRate);
|
||||||
layers_->UpdateConfiguration(0, &cfg_);
|
layers_->UpdateConfiguration(0, &cfg_);
|
||||||
|
|
||||||
EXPECT_EQ(kTl0Flags, LibvpxVp8Encoder::EncodeFlags(
|
EXPECT_EQ(kTl0Flags,
|
||||||
UpdateLayerConfig(0, kStartTimestamp)));
|
LibvpxVp8Encoder::EncodeFlags(NextFrameConfig(0, kStartTimestamp)));
|
||||||
layers_->OnEncodeDone(0, kStartTimestamp, kLargeFrameSizeBytes, false,
|
layers_->OnEncodeDone(0, kStartTimestamp, kLargeFrameSizeBytes, false,
|
||||||
kDefaultQp, IgnoredCodecSpecificInfo());
|
kDefaultQp, IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
|
@ -502,12 +502,12 @@ TEST_F(ScreenshareLayerTest, RespectsMaxIntervalBetweenFrames) {
|
||||||
// any later, the frame will be dropped anyway by the frame rate throttling
|
// any later, the frame will be dropped anyway by the frame rate throttling
|
||||||
// logic.
|
// logic.
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
UpdateLayerConfig(0, kTwoSecondsLater - kTimestampDelta5Fps).drop_frame);
|
NextFrameConfig(0, kTwoSecondsLater - kTimestampDelta5Fps).drop_frame);
|
||||||
|
|
||||||
// More than two seconds has passed since last frame, one should be emitted
|
// More than two seconds has passed since last frame, one should be emitted
|
||||||
// even if bitrate target is then exceeded.
|
// even if bitrate target is then exceeded.
|
||||||
EXPECT_EQ(kTl0Flags, LibvpxVp8Encoder::EncodeFlags(
|
EXPECT_EQ(kTl0Flags, LibvpxVp8Encoder::EncodeFlags(
|
||||||
UpdateLayerConfig(0, kTwoSecondsLater + 90)));
|
NextFrameConfig(0, kTwoSecondsLater + 90)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ScreenshareLayerTest, UpdatesHistograms) {
|
TEST_F(ScreenshareLayerTest, UpdatesHistograms) {
|
||||||
|
@ -520,7 +520,7 @@ TEST_F(ScreenshareLayerTest, UpdatesHistograms) {
|
||||||
for (int64_t timestamp = 0;
|
for (int64_t timestamp = 0;
|
||||||
timestamp < kTimestampDelta5Fps * 5 * metrics::kMinRunTimeInSeconds;
|
timestamp < kTimestampDelta5Fps * 5 * metrics::kMinRunTimeInSeconds;
|
||||||
timestamp += kTimestampDelta5Fps) {
|
timestamp += kTimestampDelta5Fps) {
|
||||||
tl_config_ = UpdateLayerConfig(0, timestamp);
|
tl_config_ = NextFrameConfig(0, timestamp);
|
||||||
if (tl_config_.drop_frame) {
|
if (tl_config_.drop_frame) {
|
||||||
dropped_frame = true;
|
dropped_frame = true;
|
||||||
continue;
|
continue;
|
||||||
|
@ -609,7 +609,7 @@ TEST_F(ScreenshareLayerTest, RespectsConfiguredFramerate) {
|
||||||
|
|
||||||
// Send at regular rate - no drops expected.
|
// Send at regular rate - no drops expected.
|
||||||
for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs) {
|
for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs) {
|
||||||
if (UpdateLayerConfig(0, timestamp).drop_frame) {
|
if (NextFrameConfig(0, timestamp).drop_frame) {
|
||||||
++num_discarded_frames;
|
++num_discarded_frames;
|
||||||
} else {
|
} else {
|
||||||
size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8;
|
size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8;
|
||||||
|
@ -627,7 +627,7 @@ TEST_F(ScreenshareLayerTest, RespectsConfiguredFramerate) {
|
||||||
num_input_frames = 0;
|
num_input_frames = 0;
|
||||||
num_discarded_frames = 0;
|
num_discarded_frames = 0;
|
||||||
for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs / 2) {
|
for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs / 2) {
|
||||||
if (UpdateLayerConfig(0, timestamp).drop_frame) {
|
if (NextFrameConfig(0, timestamp).drop_frame) {
|
||||||
++num_discarded_frames;
|
++num_discarded_frames;
|
||||||
} else {
|
} else {
|
||||||
size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8;
|
size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8;
|
||||||
|
@ -669,7 +669,7 @@ TEST_F(ScreenshareLayerTest, DropOnTooShortFrameInterval) {
|
||||||
|
|
||||||
// Add a large gap, so there's plenty of room in the rate tracker.
|
// Add a large gap, so there's plenty of room in the rate tracker.
|
||||||
timestamp_ += kTimestampDelta5Fps * 3;
|
timestamp_ += kTimestampDelta5Fps * 3;
|
||||||
EXPECT_FALSE(UpdateLayerConfig(0, timestamp_).drop_frame);
|
EXPECT_FALSE(NextFrameConfig(0, timestamp_).drop_frame);
|
||||||
layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
|
layers_->OnEncodeDone(0, timestamp_, frame_size_, false, kDefaultQp,
|
||||||
IgnoredCodecSpecificInfo());
|
IgnoredCodecSpecificInfo());
|
||||||
|
|
||||||
|
@ -677,11 +677,11 @@ TEST_F(ScreenshareLayerTest, DropOnTooShortFrameInterval) {
|
||||||
// frame just before this limit.
|
// frame just before this limit.
|
||||||
const int64_t kMinFrameInterval = (kTimestampDelta5Fps * 85) / 100;
|
const int64_t kMinFrameInterval = (kTimestampDelta5Fps * 85) / 100;
|
||||||
timestamp_ += kMinFrameInterval - 90;
|
timestamp_ += kMinFrameInterval - 90;
|
||||||
EXPECT_TRUE(UpdateLayerConfig(0, timestamp_).drop_frame);
|
EXPECT_TRUE(NextFrameConfig(0, timestamp_).drop_frame);
|
||||||
|
|
||||||
// Try again at the limit, now it should pass.
|
// Try again at the limit, now it should pass.
|
||||||
timestamp_ += 90;
|
timestamp_ += 90;
|
||||||
EXPECT_FALSE(UpdateLayerConfig(0, timestamp_).drop_frame);
|
EXPECT_FALSE(NextFrameConfig(0, timestamp_).drop_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ScreenshareLayerTest, AdjustsBitrateWhenDroppingFrames) {
|
TEST_F(ScreenshareLayerTest, AdjustsBitrateWhenDroppingFrames) {
|
||||||
|
|
|
@ -37,7 +37,7 @@ constexpr uint32_t kSimulcastScreenshareMaxBitrateKbps = 1250;
|
||||||
|
|
||||||
class MockTemporalLayers : public Vp8FrameBufferController {
|
class MockTemporalLayers : public Vp8FrameBufferController {
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD2(UpdateLayerConfig, Vp8FrameConfig(size_t, uint32_t));
|
MOCK_METHOD2(NextFrameConfig, Vp8FrameConfig(size_t, uint32_t));
|
||||||
MOCK_METHOD3(OnRatesUpdated, void(size_t, const std::vector<uint32_t>&, int));
|
MOCK_METHOD3(OnRatesUpdated, void(size_t, const std::vector<uint32_t>&, int));
|
||||||
MOCK_METHOD2(UpdateConfiguration, bool(size_t, Vp8EncoderConfig*));
|
MOCK_METHOD2(UpdateConfiguration, bool(size_t, Vp8EncoderConfig*));
|
||||||
MOCK_METHOD6(OnEncodeDone,
|
MOCK_METHOD6(OnEncodeDone,
|
||||||
|
|
|
@ -93,7 +93,7 @@ std::unique_ptr<RTPFragmentationHeader> FakeVP8Encoder::EncodeHook(
|
||||||
CodecSpecificInfo* codec_specific) {
|
CodecSpecificInfo* codec_specific) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
uint8_t stream_idx = encoded_image->SpatialIndex().value_or(0);
|
uint8_t stream_idx = encoded_image->SpatialIndex().value_or(0);
|
||||||
frame_buffer_controller_->UpdateLayerConfig(stream_idx,
|
frame_buffer_controller_->NextFrameConfig(stream_idx,
|
||||||
encoded_image->Timestamp());
|
encoded_image->Timestamp());
|
||||||
PopulateCodecSpecific(codec_specific, encoded_image->size(),
|
PopulateCodecSpecific(codec_specific, encoded_image->size(),
|
||||||
encoded_image->_frameType, stream_idx,
|
encoded_image->_frameType, stream_idx,
|
||||||
|
|
Loading…
Reference in a new issue