blob: 37de5d2cbfd01fad84e8401237fba003cab5d536 [file] [log] [blame]
Mudassir Galagnath5e9ed982022-09-29 17:39:20 +05301/*
2 * Copyright (c) 2022, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12#include <memory>
13#include <string>
14#include <utility>
15#include <vector>
16
17#include "test/codec_factory.h"
18#include "test/encode_test_driver.h"
19#include "test/md5_helper.h"
20#include "test/util.h"
21#include "test/yuv_video_source.h"
22
23namespace {
24
25class PostprocFiltersTest
26 : public ::libaom_test::CodecTestWith2Params<int, unsigned int>,
27 public ::libaom_test::EncoderTest {
28 protected:
29 PostprocFiltersTest()
30 : EncoderTest(GET_PARAM(0)), set_skip_postproc_filtering_(false),
31 frame_number_(0), cpu_used_(GET_PARAM(1)), bd_(GET_PARAM(2)) {}
32
33 virtual void SetUp() {
34 InitializeConfig(::libaom_test::kAllIntra);
35 cfg_.g_input_bit_depth = bd_;
36 }
37
38 virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
39 ::libaom_test::Encoder *encoder) {
40 frame_number_ = video->frame();
41 if (frame_number_ == 0) {
42 encoder->Control(AOME_SET_CPUUSED, cpu_used_);
43 encoder->Control(AOME_SET_CQ_LEVEL, kCqLevel);
44 }
45 if (set_skip_postproc_filtering_) {
46 if (frame_number_ == 0) {
47 encoder->Control(AV1E_SET_SKIP_POSTPROC_FILTERING, 1);
48 } else if (frame_number_ == 10) {
49 encoder->Control(AV1E_SET_SKIP_POSTPROC_FILTERING, 0);
50 } else if (frame_number_ == 20) {
51 encoder->Control(AV1E_SET_SKIP_POSTPROC_FILTERING, 1);
52 }
53 }
54 }
55
56 virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) {
57 ::libaom_test::MD5 md5_enc;
58 md5_enc.Add(reinterpret_cast<uint8_t *>(pkt->data.frame.buf),
59 pkt->data.frame.sz);
60 md5_enc_.push_back(md5_enc.Get());
61 }
62
63 virtual void PostEncodeFrameHook(::libaom_test::Encoder *encoder) {
64 const aom_image_t *img_enc = encoder->GetPreviewFrame();
65 if (!set_skip_postproc_filtering_) {
66 ASSERT_NE(img_enc, nullptr);
67 } else {
68 // Null will be returned if we query the reconstructed frame when
69 // AV1E_SET_SKIP_POSTPROC_FILTERING is set to 1.
70 if (frame_number_ < 10) {
71 ASSERT_EQ(img_enc, nullptr);
72 } else if (frame_number_ < 20) {
73 // Reconstructed frame cannot be null when
74 // AV1E_SET_SKIP_POSTPROC_FILTERING is set to 0.
75 ASSERT_NE(img_enc, nullptr);
76 } else {
77 ASSERT_EQ(img_enc, nullptr);
78 }
79 }
80 }
81
82 // The encoder config flag 'AV1E_SET_SKIP_POSTPROC_FILTERING' can be used to
83 // skip the application of post-processing filters on reconstructed frame for
84 // ALLINTRA encode. This unit-test validates the bit exactness of 2 encoded
85 // streams with 'AV1E_SET_SKIP_POSTPROC_FILTERING':
86 // 1. disabled for all frames (default case)
87 // 2. enabled and disabled at different frame indices using control calls.
88 void DoTest() {
89 std::unique_ptr<libaom_test::VideoSource> video(
90 new libaom_test::YUVVideoSource("niklas_640_480_30.yuv",
91 AOM_IMG_FMT_I420, 640, 480, 30, 1, 0,
92 kFrames));
93 ASSERT_NE(video, nullptr);
94
95 // First encode: 'AV1E_SET_SKIP_POSTPROC_FILTERING' disabled for all frames
96 // (default case).
97 set_skip_postproc_filtering_ = false;
98 ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
99 std::vector<std::string> apply_postproc_filters_md5_enc =
100 std::move(md5_enc_);
101 md5_enc_.clear();
102
103 // Second encode: 'AV1E_SET_SKIP_POSTPROC_FILTERING' enabled and disabled at
104 // different frame intervals.
105 set_skip_postproc_filtering_ = true;
106 ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
107 std::vector<std::string> toggle_apply_postproc_filters_md5_enc =
108 std::move(md5_enc_);
109 md5_enc_.clear();
110
111 // Check for bit match.
112 ASSERT_EQ(apply_postproc_filters_md5_enc,
113 toggle_apply_postproc_filters_md5_enc);
114 }
115
116 bool set_skip_postproc_filtering_;
117 unsigned int frame_number_;
118 std::vector<std::string> md5_enc_;
119
120 private:
121 static constexpr int kFrames = 30;
122 static constexpr unsigned int kCqLevel = 18;
123 int cpu_used_;
124 unsigned int bd_;
125};
126
127class PostprocFiltersTestLarge : public PostprocFiltersTest {};
128
129TEST_P(PostprocFiltersTest, MD5Match) { DoTest(); }
130
131TEST_P(PostprocFiltersTestLarge, MD5Match) { DoTest(); }
132
133AV1_INSTANTIATE_TEST_SUITE(PostprocFiltersTest, ::testing::Values(9),
134 ::testing::Values(8, 10));
135
136// Test cpu_used 3 and 6.
137AV1_INSTANTIATE_TEST_SUITE(PostprocFiltersTestLarge, ::testing::Values(3, 6),
138 ::testing::Values(8, 10));
139
140} // namespace