1 // Copyright 2024 Google LLC
2 // SPDX-License-Identifier: BSD-2-Clause
3
4 #include <array>
5 #include <string>
6
7 #include "avif/avif.h"
8 #include "aviftest_helpers.h"
9 #include "gtest/gtest.h"
10
11 namespace avif {
12 namespace {
13
14 // Used to pass the data folder path to the GoogleTest suites.
15 const char* data_path = nullptr;
16
TEST(KeyframeTest,Decode)17 TEST(KeyframeTest, Decode) {
18 if (!testutil::Av1DecoderAvailable()) {
19 GTEST_SKIP() << "AV1 Codec unavailable, skip test.";
20 }
21
22 DecoderPtr decoder(avifDecoderCreate());
23 ASSERT_NE(decoder, nullptr);
24 const std::string file_name = "colors-animated-12bpc-keyframes-0-2-3.avif";
25 ASSERT_EQ(
26 avifDecoderSetIOFile(decoder.get(), (data_path + file_name).c_str()),
27 AVIF_RESULT_OK);
28 ASSERT_EQ(avifDecoderParse(decoder.get()), AVIF_RESULT_OK);
29 EXPECT_EQ(decoder->compressionFormat, COMPRESSION_FORMAT_AVIF);
30
31 // The first frame is always a keyframe.
32 EXPECT_TRUE(avifDecoderIsKeyframe(decoder.get(), 0));
33 EXPECT_EQ(avifDecoderNearestKeyframe(decoder.get(), 0), 0);
34
35 // The encoder may choose to use a keyframe here, even without FORCE_KEYFRAME.
36 // It seems not to.
37 EXPECT_FALSE(avifDecoderIsKeyframe(decoder.get(), 1));
38 EXPECT_EQ(avifDecoderNearestKeyframe(decoder.get(), 1), 0);
39
40 EXPECT_TRUE(avifDecoderIsKeyframe(decoder.get(), 2));
41 EXPECT_EQ(avifDecoderNearestKeyframe(decoder.get(), 2), 2);
42
43 // The encoder seems to prefer a keyframe here
44 // (gradient too different from plain color).
45 EXPECT_TRUE(avifDecoderIsKeyframe(decoder.get(), 3));
46 EXPECT_EQ(avifDecoderNearestKeyframe(decoder.get(), 3), 3);
47
48 // This is the same frame as the previous one. It should not be a keyframe.
49 EXPECT_FALSE(avifDecoderIsKeyframe(decoder.get(), 4));
50 EXPECT_EQ(avifDecoderNearestKeyframe(decoder.get(), 4), 3);
51 }
52
53 } // namespace
54 } // namespace avif
55
main(int argc,char ** argv)56 int main(int argc, char** argv) {
57 ::testing::InitGoogleTest(&argc, argv);
58 if (argc != 2) {
59 std::cerr << "There must be exactly one argument containing the path to "
60 "the test data folder"
61 << std::endl;
62 return 1;
63 }
64 avif::data_path = argv[1];
65 return RUN_ALL_TESTS();
66 }
67