• 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 #include "iamf/cli/codec/encoder_base.h"
13 
14 #include <cstdint>
15 #include <list>
16 #include <memory>
17 #include <utility>
18 #include <vector>
19 
20 #include "absl/status/status.h"
21 #include "absl/status/status_matchers.h"
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "iamf/cli/audio_frame_with_data.h"
25 #include "iamf/obu/audio_frame.h"
26 #include "iamf/obu/codec_config.h"
27 #include "iamf/obu/obu_header.h"
28 #include "iamf/obu/types.h"
29 
30 namespace iamf_tools {
31 namespace {
32 
33 using ::absl_testing::IsOk;
34 
35 using testing::Return;
36 
37 constexpr DecodedUleb128 kCodecConfigId = 159;
38 constexpr bool kValidateCodecDelay = true;
39 constexpr bool kDontValidateCodecDelay = false;
40 
41 class MockEncoder : public EncoderBase {
42  public:
MockEncoder()43   MockEncoder()
44       : EncoderBase(CodecConfigObu(ObuHeader(), kCodecConfigId, CodecConfig()),
45                     0) {}
46 
47   MOCK_METHOD(
48       absl::Status, EncodeAudioFrame,
49       (int input_bit_depth, const std::vector<std::vector<int32_t>>& samples,
50        std::unique_ptr<AudioFrameWithData> partial_audio_frame_with_data),
51       (override));
52 
53   MOCK_METHOD(absl::Status, InitializeEncoder, (), (override));
54   MOCK_METHOD(absl::Status, SetNumberOfSamplesToDelayAtStart,
55               (bool validate_codec_delay), (override));
56 };
57 
TEST(EncoderBaseTest,InitializeSucceeds)58 TEST(EncoderBaseTest, InitializeSucceeds) {
59   MockEncoder encoder;
60   EXPECT_CALL(encoder, InitializeEncoder()).WillOnce(Return(absl::OkStatus()));
61   EXPECT_CALL(encoder, SetNumberOfSamplesToDelayAtStart(kValidateCodecDelay))
62       .WillOnce(Return(absl::OkStatus()));
63 
64   EXPECT_THAT(encoder.Initialize(kValidateCodecDelay), IsOk());
65 }
66 
TEST(EncoderBaseTest,InitializeFailsWhenInitializeEncoderFails)67 TEST(EncoderBaseTest, InitializeFailsWhenInitializeEncoderFails) {
68   MockEncoder encoder;
69   EXPECT_CALL(encoder, InitializeEncoder())
70       .WillOnce(Return(absl::UnknownError("")));
71 
72   EXPECT_EQ(encoder.Initialize(kValidateCodecDelay).code(),
73             absl::StatusCode::kUnknown);
74 }
75 
TEST(EncoderBaseTest,InitializePropagatesValidatePreSkipToSetNumberOfSamplesToDelayAtStart)76 TEST(EncoderBaseTest,
77      InitializePropagatesValidatePreSkipToSetNumberOfSamplesToDelayAtStart) {
78   MockEncoder encoder;
79   EXPECT_CALL(encoder,
80               SetNumberOfSamplesToDelayAtStart(kDontValidateCodecDelay));
81 
82   encoder.Initialize(kDontValidateCodecDelay).IgnoreError();
83 }
84 
TEST(EncoderBaseTest,SetNumberOfSamplesToDelayAtStartDefaultsToSuccess)85 TEST(EncoderBaseTest, SetNumberOfSamplesToDelayAtStartDefaultsToSuccess) {
86   MockEncoder encoder;
87   EXPECT_CALL(encoder, SetNumberOfSamplesToDelayAtStart(kValidateCodecDelay));
88 
89   EXPECT_THAT(encoder.Initialize(kValidateCodecDelay), IsOk());
90 }
91 
TEST(EncoderBaseTest,InitializeFailsWhenSetNumberOfSamplesToDelayAtStartFails)92 TEST(EncoderBaseTest,
93      InitializeFailsWhenSetNumberOfSamplesToDelayAtStartFails) {
94   MockEncoder encoder;
95   EXPECT_CALL(encoder, InitializeEncoder()).WillOnce(Return(absl::OkStatus()));
96   EXPECT_CALL(encoder, SetNumberOfSamplesToDelayAtStart(kValidateCodecDelay))
97       .WillOnce(Return(absl::UnknownError("")));
98 
99   EXPECT_EQ(encoder.Initialize(kValidateCodecDelay).code(),
100             absl::StatusCode::kUnknown);
101 }
102 
TEST(EncoderBaseTest,FinalizeAndPopAppendNothingWhenNoFramesAvailable)103 TEST(EncoderBaseTest, FinalizeAndPopAppendNothingWhenNoFramesAvailable) {
104   MockEncoder encoder;
105 
106   // Expect the returned `audio_frames` is just the same as before calling
107   // `Finalize()` and `Pop()`, because we know an empty list
108   // (`finalized_audio_frames_`) is appended at the end.
109   const DecodedUleb128 kSubstreamId = 137;
110   const int32_t kStartTimestamp = 77;
111   const int32_t kEndTimestamp = 101;
112   const std::vector<uint8_t> kAudioFrame = {1, 7, 5, 3};
113   AudioFrameObu obu(ObuHeader(), kSubstreamId, kAudioFrame);
114   std::list<AudioFrameWithData> audio_frames;
115   audio_frames.emplace_back(AudioFrameWithData{
116       .obu = std::move(obu),
117       .start_timestamp = kStartTimestamp,
118       .end_timestamp = kEndTimestamp,
119       .audio_element_with_data = nullptr,
120   });
121 
122   EXPECT_THAT(encoder.Finalize(), IsOk());
123 
124   // Since nothing has been added, there are no frames available.
125   EXPECT_FALSE(encoder.FramesAvailable());
126 
127   // `Pop()` still works, just adding nothing.
128   EXPECT_THAT(encoder.Pop(audio_frames), IsOk());
129 
130   // Expect the `audio_frames` is unaltered.
131   ASSERT_EQ(audio_frames.size(), 1);
132   const auto& only_frame = audio_frames.back();
133   EXPECT_EQ(only_frame.obu.GetSubstreamId(), kSubstreamId);
134   EXPECT_EQ(only_frame.obu.audio_frame_, kAudioFrame);
135   EXPECT_EQ(only_frame.start_timestamp, kStartTimestamp);
136   EXPECT_EQ(only_frame.end_timestamp, kEndTimestamp);
137   EXPECT_EQ(only_frame.audio_element_with_data, nullptr);
138 }
139 
TEST(EncoderBaseTest,DefaultZeroNumberOfSamplesToDelayAtStart)140 TEST(EncoderBaseTest, DefaultZeroNumberOfSamplesToDelayAtStart) {
141   MockEncoder encoder;
142 
143   EXPECT_EQ(encoder.GetNumberOfSamplesToDelayAtStart(), 0);
144 }
145 
146 }  // namespace
147 }  // namespace iamf_tools
148