• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023, Alliance for Open Media. All rights reserved
3  *
4  * This source code is subject to the terms of the BSD 3-Clause Clear License
5  * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
6  * License was not distributed with this source code in the LICENSE file, you
7  * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the
8  * Alliance for Open Media Patent License 1.0 was not distributed with this
9  * source code in the PATENTS file, you can obtain it at
10  * www.aomedia.org/license/patent.
11  */
12 #ifndef CLI_TESTS_ENCODER_TEST_BASE_H_
13 #define CLI_TESTS_ENCODER_TEST_BASE_H_
14 
15 #include <cstdint>
16 #include <list>
17 #include <memory>
18 #include <utility>
19 #include <vector>
20 
21 #include "absl/memory/memory.h"
22 #include "absl/status/status.h"
23 #include "absl/status/status_matchers.h"
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 #include "iamf/cli/audio_frame_with_data.h"
27 #include "iamf/cli/codec/encoder_base.h"
28 #include "iamf/obu/audio_frame.h"
29 
30 namespace iamf_tools {
31 
32 using ::absl_testing::IsOk;
33 
34 constexpr bool kValidateCodecDelay = true;
35 
36 class EncoderTestBase {
37  public:
38   EncoderTestBase() = default;
39   virtual ~EncoderTestBase() = 0;
40 
41  protected:
42   virtual void ConstructEncoder() = 0;
43 
InitExpectOk()44   void InitExpectOk() {
45     ConstructEncoder();
46     EXPECT_THAT(encoder_->Initialize(kValidateCodecDelay), IsOk());
47   }
48 
49   void EncodeAudioFrame(const std::vector<std::vector<int32_t>>& pcm_samples,
50                         bool expected_encode_frame_is_ok = true) {
51     // `EncodeAudioFrame` only passes on most of the data in the input
52     // `AudioFrameWithData`. Simulate the timestamp to ensure frames are
53     // returned in the correct order, but most other fields do not matter.
54     const int32_t next_timestamp =
55         cur_timestamp_ + static_cast<int32_t>(num_samples_per_frame_);
56     auto partial_audio_frame_with_data =
57         absl::WrapUnique(new AudioFrameWithData{
58             .obu = AudioFrameObu(
59                 {
60                     .obu_trimming_status_flag = false,
61                     .num_samples_to_trim_at_end = 0,
62                     .num_samples_to_trim_at_start = 0,
63                 },
64                 0, {}),
65             .start_timestamp = cur_timestamp_,
66             .end_timestamp = next_timestamp,
67         });
68     cur_timestamp_ = next_timestamp;
69 
70     // Encode the frame as requested.
71     EXPECT_EQ(encoder_
72                   ->EncodeAudioFrame(input_sample_size_, pcm_samples,
73                                      std::move(partial_audio_frame_with_data))
74                   .ok(),
75               expected_encode_frame_is_ok);
76   }
77 
78   // Finalizes the encoder and only validates the number and order of output
79   // frames is consistent with the input frames. Returns the output audio
80   // frames.
FinalizeAndValidateOrderOnly(int expected_num_frames)81   std::list<AudioFrameWithData> FinalizeAndValidateOrderOnly(
82       int expected_num_frames) {
83     std::list<AudioFrameWithData> output_audio_frames;
84     EXPECT_THAT(encoder_->Finalize(), IsOk());
85 
86     // Pop all the frames.
87     for (int i = 0; i < expected_num_frames; i++) {
88       EXPECT_THAT(encoder_->Pop(output_audio_frames), IsOk());
89     }
90     EXPECT_EQ(output_audio_frames.size(), expected_num_frames);
91 
92     // Check that there are no more frames left.
93     EXPECT_FALSE(encoder_->FramesAvailable());
94 
95     ValidateOrder(output_audio_frames);
96     return output_audio_frames;
97   }
98 
99   // Finalizes the encoder and validates the content of the `audio_frame_`s
100   // matches the expected data in the expected order.
FinalizeAndValidate()101   void FinalizeAndValidate() {
102     const auto output_audio_frames =
103         FinalizeAndValidateOrderOnly(expected_audio_frames_.size());
104 
105     // Validate the `audio_frame_` data is identical to the expected data.
106     EXPECT_EQ(output_audio_frames.size(), expected_audio_frames_.size());
107     auto output_iter = output_audio_frames.begin();
108     auto expected_iter = expected_audio_frames_.begin();
109     while (output_iter != output_audio_frames.end()) {
110       EXPECT_EQ(output_iter->obu.audio_frame_, *expected_iter);
111       output_iter++;
112       expected_iter++;
113     }
114   }
115 
116   int num_channels_ = 1;
117   int substream_id_ = 0;
118   uint32_t num_samples_per_frame_ = 1;
119   int8_t input_sample_size_ = 16;
120   std::unique_ptr<EncoderBase> encoder_;
121 
122   std::list<std::vector<uint8_t>> expected_audio_frames_ = {};
123 
124  private:
ValidateOrder(const std::list<AudioFrameWithData> & output_audio_frames)125   void ValidateOrder(const std::list<AudioFrameWithData>& output_audio_frames) {
126     // Validate that the timestamps match the expected order.
127     int expected_start_timestamp_ = 0;
128     for (const auto& output_audio_frame : output_audio_frames) {
129       EXPECT_EQ(output_audio_frame.start_timestamp, expected_start_timestamp_);
130       expected_start_timestamp_ += num_samples_per_frame_;
131     }
132   }
133 
134   int32_t cur_timestamp_ = 0;
135 };
136 
137 }  // namespace iamf_tools
138 
139 #endif  // CLI_TESTS_ENCODER_TEST_BASE_H_
140