mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00

When spatial scalability is used, both vpx and aom set key frame flag for all spatial layers of the first frame, while rtp code expect it to be set only on the frame without spatial dependencies. That creates confusion for the frame dependency calculator. Simplest solution seems to ignore that confusing signal and instead rely encoder wrappers update frame buffer usages when key frame is generated. Bug: webrtc:11999 Change-Id: Ica24f1d8d42d32dd24664beabf32ac24872cd15a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/194002 Reviewed-by: Philip Eliasson <philipel@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32667}
121 lines
4.8 KiB
C++
121 lines
4.8 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/frame_dependencies_calculator.h"
|
|
|
|
#include "common_video/generic_frame_descriptor/generic_frame_info.h"
|
|
#include "test/gmock.h"
|
|
#include "test/gtest.h"
|
|
|
|
namespace webrtc {
|
|
namespace {
|
|
|
|
using ::testing::ElementsAre;
|
|
using ::testing::IsEmpty;
|
|
using ::testing::UnorderedElementsAre;
|
|
|
|
constexpr CodecBufferUsage ReferenceAndUpdate(int id) {
|
|
return CodecBufferUsage(id, /*referenced=*/true, /*updated=*/true);
|
|
}
|
|
constexpr CodecBufferUsage Reference(int id) {
|
|
return CodecBufferUsage(id, /*referenced=*/true, /*updated=*/false);
|
|
}
|
|
constexpr CodecBufferUsage Update(int id) {
|
|
return CodecBufferUsage(id, /*referenced=*/false, /*updated=*/true);
|
|
}
|
|
|
|
TEST(FrameDependenciesCalculatorTest, SingleLayer) {
|
|
CodecBufferUsage pattern[] = {ReferenceAndUpdate(0)};
|
|
FrameDependenciesCalculator calculator;
|
|
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/1, pattern), IsEmpty());
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/3, pattern),
|
|
ElementsAre(1));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/6, pattern),
|
|
ElementsAre(3));
|
|
}
|
|
|
|
TEST(FrameDependenciesCalculatorTest, TwoTemporalLayers) {
|
|
// Shortened 4-frame pattern:
|
|
// T1: 2---4 6---8 ...
|
|
// / / / /
|
|
// T0: 1---3---5---7 ...
|
|
CodecBufferUsage pattern0[] = {ReferenceAndUpdate(0)};
|
|
CodecBufferUsage pattern1[] = {Reference(0), Update(1)};
|
|
CodecBufferUsage pattern2[] = {ReferenceAndUpdate(0)};
|
|
CodecBufferUsage pattern3[] = {Reference(0), Reference(1)};
|
|
FrameDependenciesCalculator calculator;
|
|
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/1, pattern0), IsEmpty());
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/2, pattern1),
|
|
ElementsAre(1));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/3, pattern2),
|
|
ElementsAre(1));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/4, pattern3),
|
|
UnorderedElementsAre(2, 3));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/5, pattern0),
|
|
ElementsAre(3));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/6, pattern1),
|
|
ElementsAre(5));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/7, pattern2),
|
|
ElementsAre(5));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/8, pattern3),
|
|
UnorderedElementsAre(6, 7));
|
|
}
|
|
|
|
TEST(FrameDependenciesCalculatorTest, ThreeTemporalLayers4FramePattern) {
|
|
// T2: 2---4 6---8 ...
|
|
// / / / /
|
|
// T1: | 3 | 7 ...
|
|
// /_/ /_/
|
|
// T0: 1-------5----- ...
|
|
CodecBufferUsage pattern0[] = {ReferenceAndUpdate(0)};
|
|
CodecBufferUsage pattern1[] = {Reference(0), Update(2)};
|
|
CodecBufferUsage pattern2[] = {Reference(0), Update(1)};
|
|
CodecBufferUsage pattern3[] = {Reference(0), Reference(1), Reference(2)};
|
|
FrameDependenciesCalculator calculator;
|
|
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/1, pattern0), IsEmpty());
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/2, pattern1),
|
|
ElementsAre(1));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/3, pattern2),
|
|
ElementsAre(1));
|
|
// Note that frame#4 references buffer#0 that is updated by frame#1,
|
|
// yet there is no direct dependency from frame#4 to frame#1.
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/4, pattern3),
|
|
UnorderedElementsAre(2, 3));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/5, pattern0),
|
|
ElementsAre(1));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/6, pattern1),
|
|
ElementsAre(5));
|
|
}
|
|
|
|
TEST(FrameDependenciesCalculatorTest, SimulcastWith2Layers) {
|
|
// S1: 2---4---6- ...
|
|
//
|
|
// S0: 1---3---5- ...
|
|
CodecBufferUsage pattern0[] = {ReferenceAndUpdate(0)};
|
|
CodecBufferUsage pattern1[] = {ReferenceAndUpdate(1)};
|
|
FrameDependenciesCalculator calculator;
|
|
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/1, pattern0), IsEmpty());
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/2, pattern1), IsEmpty());
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/3, pattern0),
|
|
ElementsAre(1));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/4, pattern1),
|
|
ElementsAre(2));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/5, pattern0),
|
|
ElementsAre(3));
|
|
EXPECT_THAT(calculator.FromBuffersUsage(/*frame_id=*/6, pattern1),
|
|
ElementsAre(4));
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace webrtc
|