• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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