• 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/flac_encoder.h"
13 
14 #include <cstdint>
15 #include <memory>
16 #include <vector>
17 
18 #include "absl/status/status.h"
19 #include "absl/status/status_matchers.h"
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 #include "iamf/cli/codec/tests/encoder_test_base.h"
23 #include "iamf/cli/proto/codec_config.pb.h"
24 #include "iamf/obu/codec_config.h"
25 #include "iamf/obu/decoder_config/flac_decoder_config.h"
26 #include "iamf/obu/obu_header.h"
27 
28 namespace iamf_tools {
29 namespace {
30 
31 using ::absl_testing::IsOk;
32 
33 constexpr bool kOverrideAudioRollDistance = true;
34 constexpr bool kIgnoredValidateCodecDelay = true;
35 
36 class FlacEncoderTest : public EncoderTestBase, public testing::Test {
37  public:
FlacEncoderTest()38   FlacEncoderTest() {
39     flac_encoder_metadata_.set_compression_level(0);
40     num_samples_per_frame_ = 16;
41     input_sample_size_ = 32;
42   }
43 
44   ~FlacEncoderTest() = default;
45 
46  protected:
ConstructEncoder()47   void ConstructEncoder() override {
48     // Construct a Codec Config OBU. The only fields that should affect the
49     // output are `num_samples_per_frame` and `decoder_config`.
50     const CodecConfig temp = {.codec_id = CodecConfig::kCodecIdFlac,
51                               .num_samples_per_frame = num_samples_per_frame_,
52                               .decoder_config = flac_decoder_config_};
53 
54     CodecConfigObu codec_config(ObuHeader(), 0, temp);
55     ASSERT_THAT(codec_config.Initialize(kOverrideAudioRollDistance), IsOk());
56 
57     encoder_ = std::make_unique<FlacEncoder>(flac_encoder_metadata_,
58                                              codec_config, num_channels_);
59   }
60 
61   FlacDecoderConfig flac_decoder_config_ = {
62       {{.header = {.last_metadata_block_flag = true,
63                    .block_type = FlacMetaBlockHeader::kFlacStreamInfo,
64                    .metadata_data_block_length = 34},
65         .payload = FlacMetaBlockStreamInfo{.minimum_block_size = 16,
66                                            .maximum_block_size = 16,
67                                            .sample_rate = 48000,
68                                            .bits_per_sample = 31,
69                                            .total_samples_in_stream = 16}}}};
70   iamf_tools_cli_proto::FlacEncoderMetadata flac_encoder_metadata_ = {};
71 };  // namespace iamf_tools
72 
TEST_F(FlacEncoderTest,FramesAreInOrder)73 TEST_F(FlacEncoderTest, FramesAreInOrder) {
74   InitExpectOk();
75 
76   // Encode several frames and ensure the correct number of frames are output in
77   // the same order as the input.
78   const int kNumFrames = 100;
79   for (int i = 0; i < kNumFrames; i++) {
80     EncodeAudioFrame(std::vector<std::vector<int32_t>>(
81         num_samples_per_frame_, std::vector<int32_t>(num_channels_, i)));
82   }
83   FinalizeAndValidateOrderOnly(kNumFrames);
84 }
85 
TEST_F(FlacEncoderTest,InitializeFailsWhenNumSamplesPerFrameIsLessThanSixteen)86 TEST_F(FlacEncoderTest,
87        InitializeFailsWhenNumSamplesPerFrameIsLessThanSixteen) {
88   num_samples_per_frame_ = 15;
89 
90   ConstructEncoder();
91 
92   EXPECT_FALSE(encoder_->Initialize(kIgnoredValidateCodecDelay).ok());
93 }
94 
TEST_F(FlacEncoderTest,EncodeAudioFrameSucceeds)95 TEST_F(FlacEncoderTest, EncodeAudioFrameSucceeds) {
96   // Typically the user of the encoder should pad partial frames of input data
97   // before passing it into the encoder.
98   const std::vector<std::vector<int32_t>> kAudioFrameWithCorrectNumSamples(
99       num_samples_per_frame_, std::vector<int32_t>(num_channels_, 0));
100   InitExpectOk();
101 
102   EncodeAudioFrame(kAudioFrameWithCorrectNumSamples);
103 }
104 
TEST_F(FlacEncoderTest,EncodeAudioFrameFailsWhenAudioFrameIsSmallerThanNumSamplesPerFrame)105 TEST_F(FlacEncoderTest,
106        EncodeAudioFrameFailsWhenAudioFrameIsSmallerThanNumSamplesPerFrame) {
107   // Typically the user of the encoder should pad partial frames of input data
108   // before passing it into the encoder.
109   const std::vector<std::vector<int32_t>> kAudioFrameWithMissingSample(
110       num_samples_per_frame_ - 1, std::vector<int32_t>(num_channels_, 0));
111   InitExpectOk();
112 
113   EncodeAudioFrame(kAudioFrameWithMissingSample,
114                    /*expected_encode_frame_is_ok=*/false);
115 }
116 
TEST_F(FlacEncoderTest,EncodeAudioFrameFailsWhenAudioFrameIsLargerThanNumSamplesPerFrame)117 TEST_F(FlacEncoderTest,
118        EncodeAudioFrameFailsWhenAudioFrameIsLargerThanNumSamplesPerFrame) {
119   const std::vector<std::vector<int32_t>> kAudioFrameWithExtraSample(
120       num_samples_per_frame_ + 1, std::vector<int32_t>(num_channels_, 0));
121   InitExpectOk();
122 
123   EncodeAudioFrame(kAudioFrameWithExtraSample,
124                    /*expected_encode_frame_is_ok=*/false);
125 }
126 
127 }  // namespace
128 }  // namespace iamf_tools
129