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