mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-15 23:01:21 +01:00

by updating flag that T1 frame can be referenced when it is encoded rather than when it is sent for encoding. Otherwise when encoder drops T1 frame, configuration for following T2 frame would still try to reference that absent T1 frame leading to invalid references. Bug: None Change-Id: I6398275971596b0618bcf9c926f0282f74120976 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/202030 Reviewed-by: Philip Eliasson <philipel@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33002}
85 lines
3 KiB
C++
85 lines
3 KiB
C++
/*
|
|
* Copyright (c) 2020 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 "modules/video_coding/svc/scalability_structure_l3t3.h"
|
|
|
|
#include <vector>
|
|
|
|
#include "modules/video_coding/svc/scalability_structure_test_helpers.h"
|
|
#include "test/gmock.h"
|
|
#include "test/gtest.h"
|
|
|
|
namespace webrtc {
|
|
namespace {
|
|
|
|
using ::testing::IsEmpty;
|
|
using ::testing::SizeIs;
|
|
|
|
TEST(ScalabilityStructureL3T3Test, SkipS1T1FrameKeepsStructureValid) {
|
|
ScalabilityStructureL3T3 structure;
|
|
ScalabilityStructureWrapper wrapper(structure);
|
|
|
|
structure.OnRatesUpdated(EnableTemporalLayers(/*s0=*/3, /*s1=*/3));
|
|
auto frames = wrapper.GenerateFrames(/*num_temporal_units=*/1);
|
|
EXPECT_THAT(frames, SizeIs(2));
|
|
EXPECT_EQ(frames[0].temporal_id, 0);
|
|
|
|
frames = wrapper.GenerateFrames(/*num_temporal_units=*/1);
|
|
EXPECT_THAT(frames, SizeIs(2));
|
|
EXPECT_EQ(frames[0].temporal_id, 2);
|
|
|
|
structure.OnRatesUpdated(EnableTemporalLayers(/*s0=*/3, /*s1=*/0));
|
|
frames = wrapper.GenerateFrames(/*num_temporal_units=*/1);
|
|
EXPECT_THAT(frames, SizeIs(1));
|
|
EXPECT_EQ(frames[0].temporal_id, 1);
|
|
|
|
structure.OnRatesUpdated(EnableTemporalLayers(/*s0=*/3, /*s1=*/3));
|
|
// Rely on checks inside GenerateFrames frame references are valid.
|
|
frames = wrapper.GenerateFrames(/*num_temporal_units=*/1);
|
|
EXPECT_THAT(frames, SizeIs(2));
|
|
EXPECT_EQ(frames[0].temporal_id, 2);
|
|
}
|
|
|
|
TEST(ScalabilityStructureL3T3Test, SkipT1FrameByEncoderKeepsReferencesValid) {
|
|
std::vector<GenericFrameInfo> frames;
|
|
ScalabilityStructureL3T3 structure;
|
|
ScalabilityStructureWrapper wrapper(structure);
|
|
|
|
// 1st 2 temporal units (T0 and T2)
|
|
wrapper.GenerateFrames(/*num_temporal_units=*/2, frames);
|
|
// Simulate T1 frame dropped by the encoder,
|
|
// i.e. retrieve config, but skip calling OnEncodeDone.
|
|
structure.NextFrameConfig(/*restart=*/false);
|
|
// one more temporal units (T2)
|
|
wrapper.GenerateFrames(/*num_temporal_units=*/1, frames);
|
|
|
|
ASSERT_THAT(frames, SizeIs(9));
|
|
EXPECT_EQ(frames[0].temporal_id, 0);
|
|
EXPECT_EQ(frames[3].temporal_id, 2);
|
|
// T1 frame was dropped by the encoder.
|
|
EXPECT_EQ(frames[6].temporal_id, 2);
|
|
|
|
EXPECT_TRUE(wrapper.FrameReferencesAreValid(frames));
|
|
}
|
|
|
|
TEST(ScalabilityStructureL3T3Test, SwitchSpatialLayerBeforeT1Frame) {
|
|
ScalabilityStructureL3T3 structure;
|
|
ScalabilityStructureWrapper wrapper(structure);
|
|
|
|
structure.OnRatesUpdated(EnableTemporalLayers(/*s0=*/2, /*s1=*/0));
|
|
EXPECT_THAT(wrapper.GenerateFrames(1), SizeIs(1));
|
|
structure.OnRatesUpdated(EnableTemporalLayers(/*s0=*/0, /*s1=*/2));
|
|
auto frames = wrapper.GenerateFrames(1);
|
|
ASSERT_THAT(frames, SizeIs(1));
|
|
EXPECT_THAT(frames[0].frame_diffs, IsEmpty());
|
|
EXPECT_EQ(frames[0].temporal_id, 0);
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace webrtc
|