1 /*
2 * Copyright (c) 2024, 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
13 #include "iamf/cli/codec/flac_decoder.h"
14
15 #include <array>
16 #include <cstddef>
17 #include <cstdint>
18 #include <vector>
19
20 #include "absl/status/status_matchers.h"
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "include/FLAC/format.h"
24 #include "include/FLAC/ordinals.h"
25 #include "include/FLAC/stream_decoder.h"
26
27 namespace iamf_tools {
28 namespace {
29
30 using ::absl_testing::IsOk;
31 using ::testing::ElementsAreArray;
32 using ::testing::Test;
33
34 // Derived from iamf/cli/testdata/stereo_8_samples_48khz_s16le.wav @ 16 samples
35 // per frame.
36 constexpr std::array<uint8_t, 22> kFlacEncodedFrame = {
37 0xff, 0xf8, 0x6a, 0xa8, 0x00, 0x0f, 0x42, 0x00, 0x00, 0x00, 0x13,
38 0x80, 0x00, 0x80, 0x04, 0x92, 0x49, 0x00, 0x01, 0xfe, 0x81, 0xee};
39
40 constexpr uint32_t kNumSamplesPerFrame = 16;
41 constexpr int kNumChannels = 2;
42
TEST(LibflacReadCallback,SignalsEndOfStreamForEmptyFrame)43 TEST(LibflacReadCallback, SignalsEndOfStreamForEmptyFrame) {
44 FlacDecoder flac_decoder(kNumChannels, kNumSamplesPerFrame);
45 FLAC__byte buffer[1024];
46 size_t bytes = 1024;
47
48 auto status = FlacDecoder::LibFlacReadCallback(
49 /*stream_decoder=*/nullptr, buffer, &bytes, &flac_decoder);
50
51 EXPECT_EQ(status, FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM);
52 EXPECT_EQ(bytes, 0);
53 }
54
TEST(LibFlacReadCallback,SignalsAbortForTooLargeFrame)55 TEST(LibFlacReadCallback, SignalsAbortForTooLargeFrame) {
56 FlacDecoder flac_decoder(kNumChannels, kNumSamplesPerFrame);
57 FLAC__byte buffer[1024];
58 size_t bytes = 1024;
59 flac_decoder.SetEncodedFrame(std::vector<uint8_t>(1025));
60
61 auto status = FlacDecoder::LibFlacReadCallback(
62 /*stream_decoder=*/nullptr, buffer, &bytes, &flac_decoder);
63
64 EXPECT_EQ(status, FLAC__STREAM_DECODER_READ_STATUS_ABORT);
65 EXPECT_EQ(bytes, 0);
66 }
67
TEST(LibFlacReadCallback,Success)68 TEST(LibFlacReadCallback, Success) {
69 FlacDecoder flac_decoder(kNumChannels, kNumSamplesPerFrame);
70 FLAC__byte buffer[1024];
71 size_t bytes = 1028;
72 const std::vector<uint8_t> encoded_frame(1024, 1);
73 flac_decoder.SetEncodedFrame(encoded_frame);
74
75 auto status = FlacDecoder::LibFlacReadCallback(
76 /*stream_decoder=*/nullptr, buffer, &bytes, &flac_decoder);
77
78 EXPECT_EQ(status, FLAC__STREAM_DECODER_READ_STATUS_CONTINUE);
79 EXPECT_EQ(bytes, 1024);
80 EXPECT_THAT(buffer, ElementsAreArray(encoded_frame));
81 }
82
TEST(LibFlacWriteCallback,SucceedsFor32BitSamples)83 TEST(LibFlacWriteCallback, SucceedsFor32BitSamples) {
84 constexpr int kThreeSamplesPerFrame = 3;
85 FlacDecoder flac_decoder(kNumChannels, kThreeSamplesPerFrame);
86 const FLAC__Frame kFlacFrame = {.header = {.blocksize = 3,
87 .channels = kNumChannels,
88 .bits_per_sample = 32}};
89 FLAC__int32 channel_0[] = {1, 0x7fffffff, 3};
90 FLAC__int32 channel_1[] = {2, 3, 4};
91 const FLAC__int32 *const buffer[] = {channel_0, channel_1};
92
93 auto status = FlacDecoder::LibFlacWriteCallback(
94 /*stream_decoder=*/nullptr, &kFlacFrame, buffer, &flac_decoder);
95
96 EXPECT_EQ(status, FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE);
97 EXPECT_THAT(flac_decoder.GetDecodedFrame(),
98 ElementsAreArray(std::vector<std::vector<int32_t>>(
99 {{1, 2}, {0x7fffffff, 3}, {3, 4}})));
100 }
101
TEST(LibFlacWriteCallback,SucceedsFor16BitSamples)102 TEST(LibFlacWriteCallback, SucceedsFor16BitSamples) {
103 constexpr int kTwoSamplesPerFrame = 2;
104 FlacDecoder flac_decoder(kNumChannels, kTwoSamplesPerFrame);
105 const FLAC__Frame kFlacFrame = {.header = {.blocksize = 2,
106 .channels = kNumChannels,
107 .bits_per_sample = 16}};
108 FLAC__int32 channel_0[] = {0x00001111, 0x0000ffff};
109 FLAC__int32 channel_1[] = {0x00000101, 0x00002222};
110 const FLAC__int32 *const buffer[] = {channel_0, channel_1};
111
112 auto status = FlacDecoder::LibFlacWriteCallback(
113 /*stream_decoder=*/nullptr, &kFlacFrame, buffer, &flac_decoder);
114
115 EXPECT_EQ(status, FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE);
116 EXPECT_THAT(flac_decoder.GetDecodedFrame(),
117 ElementsAreArray(std::vector<std::vector<int32_t>>(
118 {{0x11110000, 0x01010000},
119 {static_cast<int32_t>(0xffff0000), 0x22220000}})));
120 }
121
TEST(LibFlacWriteCallback,ReturnsStatusAbortForMismatchedBlocksize)122 TEST(LibFlacWriteCallback, ReturnsStatusAbortForMismatchedBlocksize) {
123 constexpr int kFiveSamplesPerFrame = 5;
124 // num_samples_per_channel = 5, but the encoded frame has 3 samples per
125 // channel.
126 FlacDecoder flac_decoder(kNumChannels, kFiveSamplesPerFrame);
127 const FLAC__Frame kFlacFrame = {.header = {.blocksize = 3,
128 .channels = kNumChannels,
129 .bits_per_sample = 32}};
130 FLAC__int32 channel_0[] = {1, 0x7fffffff, 3};
131 FLAC__int32 channel_1[] = {2, 3, 4};
132 const FLAC__int32 *const buffer[] = {channel_0, channel_1};
133
134 auto status = FlacDecoder::LibFlacWriteCallback(
135 /*stream_decoder=*/nullptr, &kFlacFrame, buffer, &flac_decoder);
136
137 EXPECT_EQ(status, FLAC__STREAM_DECODER_WRITE_STATUS_ABORT);
138 }
139
TEST(Initialize,Succeeds)140 TEST(Initialize, Succeeds) {
141 FlacDecoder flac_decoder(kNumChannels, kNumSamplesPerFrame);
142
143 EXPECT_THAT(flac_decoder.Initialize(), IsOk());
144 }
145
TEST(DecodeAudioFrame,Succeeds)146 TEST(DecodeAudioFrame, Succeeds) {
147 FlacDecoder flac_decoder(kNumChannels, kNumSamplesPerFrame);
148
149 EXPECT_THAT(flac_decoder.Initialize(), IsOk());
150 auto status = flac_decoder.DecodeAudioFrame(
151 std::vector(kFlacEncodedFrame.begin(), kFlacEncodedFrame.end()));
152 EXPECT_THAT(status, IsOk());
153
154 const std::vector<std::vector<int32_t>> kExpectedDecodedSamples = {
155 {0x00010000, static_cast<int32_t>(0xffff0000)},
156 {0x00020000, static_cast<int32_t>(0xfffe0000)},
157 {0x00030000, static_cast<int32_t>(0xfffd0000)},
158 {0x00040000, static_cast<int32_t>(0xfffc0000)},
159 {0x00050000, static_cast<int32_t>(0xfffb0000)},
160 {0x00060000, static_cast<int32_t>(0xfffa0000)},
161 {0x00070000, static_cast<int32_t>(0xfff90000)},
162 {0x00080000, static_cast<int32_t>(0xfff80000)},
163 {0x00000000, 0x00000000},
164 {0x00000000, 0x00000000},
165 {0x00000000, 0x00000000},
166 {0x00000000, 0x00000000},
167 {0x00000000, 0x00000000},
168 {0x00000000, 0x00000000},
169 {0x00000000, 0x00000000},
170 {0x00000000, 0x00000000}};
171 EXPECT_EQ(flac_decoder.ValidDecodedSamples(), kExpectedDecodedSamples);
172
173 // Decode again.
174 status = flac_decoder.DecodeAudioFrame(
175 std::vector(kFlacEncodedFrame.begin(), kFlacEncodedFrame.end()));
176 EXPECT_THAT(status, IsOk());
177 EXPECT_EQ(flac_decoder.ValidDecodedSamples(), kExpectedDecodedSamples);
178 }
179
TEST(DecodeAudioFrame,FailsOnMismatchedBlocksize)180 TEST(DecodeAudioFrame, FailsOnMismatchedBlocksize) {
181 constexpr uint32_t kNumSamplesPerFrame = 32;
182 // num_samples_per_channel = 32, but the encoded frame has 16 samples per
183 // channel.
184 FlacDecoder flac_decoder(kNumChannels, kNumSamplesPerFrame);
185 EXPECT_THAT(flac_decoder.Initialize(), IsOk());
186
187 auto status = flac_decoder.DecodeAudioFrame(
188 std::vector(kFlacEncodedFrame.begin(), kFlacEncodedFrame.end()));
189
190 EXPECT_FALSE(status.ok());
191 }
192
193 } // namespace
194
195 } // namespace iamf_tools
196