xref: /aosp_15_r20/external/libldac/fuzzer/libldac_encode_fuzzer.cc (revision aef9bcd9217ad2365ebc8e70efaf94b64e04df14)
1*aef9bcd9SKiyoung Kim // Copyright 2019 The Chromium Authors. All rights reserved.
2*aef9bcd9SKiyoung Kim // Use of this source code is governed by a BSD-style license that can be
3*aef9bcd9SKiyoung Kim // found in the LICENSE file.
4*aef9bcd9SKiyoung Kim 
5*aef9bcd9SKiyoung Kim #include <stdint.h>
6*aef9bcd9SKiyoung Kim #include <stddef.h>
7*aef9bcd9SKiyoung Kim #include "ldacBT.h"
8*aef9bcd9SKiyoung Kim 
9*aef9bcd9SKiyoung Kim #include <functional>
10*aef9bcd9SKiyoung Kim #include <fuzzer/FuzzedDataProvider.h>
11*aef9bcd9SKiyoung Kim #include <vector>
12*aef9bcd9SKiyoung Kim 
13*aef9bcd9SKiyoung Kim constexpr LDACBT_SMPL_FMT_T kFormat[] = {
14*aef9bcd9SKiyoung Kim     LDACBT_SMPL_FMT_S16, LDACBT_SMPL_FMT_S24, LDACBT_SMPL_FMT_S32,
15*aef9bcd9SKiyoung Kim     LDACBT_SMPL_FMT_F32};
16*aef9bcd9SKiyoung Kim constexpr int32_t kEqmidValue[] = {LDACBT_EQMID_HQ, LDACBT_EQMID_SQ,
17*aef9bcd9SKiyoung Kim                                    LDACBT_EQMID_MQ};
18*aef9bcd9SKiyoung Kim constexpr int32_t kChannel[] = {LDACBT_CHANNEL_MODE_STEREO,
19*aef9bcd9SKiyoung Kim                                 LDACBT_CHANNEL_MODE_DUAL_CHANNEL,
20*aef9bcd9SKiyoung Kim                                 LDACBT_CHANNEL_MODE_MONO};
21*aef9bcd9SKiyoung Kim constexpr int32_t kSamplingFrequency[] = {44100, 48000, 2 * 44100, 2 * 48000};
22*aef9bcd9SKiyoung Kim constexpr int32_t kLdacBtRequiredMtu = 679;
23*aef9bcd9SKiyoung Kim constexpr int32_t kMaxWlValue = 4;
24*aef9bcd9SKiyoung Kim constexpr int32_t kMinChValue = 1;
25*aef9bcd9SKiyoung Kim constexpr int32_t kMaxChValue = 2;
26*aef9bcd9SKiyoung Kim constexpr int32_t kOutputSize = 1024;
27*aef9bcd9SKiyoung Kim 
28*aef9bcd9SKiyoung Kim class Codec {
29*aef9bcd9SKiyoung Kim public:
Codec(const uint8_t * data,size_t size)30*aef9bcd9SKiyoung Kim   Codec(const uint8_t *data, size_t size) : mFdp(data, size){};
~Codec()31*aef9bcd9SKiyoung Kim   ~Codec() { deInitEncoder(); }
32*aef9bcd9SKiyoung Kim   bool initEncoder();
33*aef9bcd9SKiyoung Kim   void deInitEncoder();
34*aef9bcd9SKiyoung Kim   void encodeFrames(const uint8_t *data, size_t size);
35*aef9bcd9SKiyoung Kim   void getSamplingFrequeny();
36*aef9bcd9SKiyoung Kim   void getBitrate();
37*aef9bcd9SKiyoung Kim   void getVersion();
38*aef9bcd9SKiyoung Kim   FuzzedDataProvider mFdp;
39*aef9bcd9SKiyoung Kim 
40*aef9bcd9SKiyoung Kim private:
41*aef9bcd9SKiyoung Kim   int32_t mChannel;
42*aef9bcd9SKiyoung Kim   LDACBT_SMPL_FMT_T mFormat;
43*aef9bcd9SKiyoung Kim   HANDLE_LDAC_BT mHandleLdacBt;
44*aef9bcd9SKiyoung Kim };
45*aef9bcd9SKiyoung Kim 
initEncoder()46*aef9bcd9SKiyoung Kim bool Codec::initEncoder() {
47*aef9bcd9SKiyoung Kim   mHandleLdacBt = ldacBT_get_handle();
48*aef9bcd9SKiyoung Kim 
49*aef9bcd9SKiyoung Kim   mChannel = mFdp.PickValueInArray(kChannel);
50*aef9bcd9SKiyoung Kim   mFormat = mFdp.PickValueInArray(kFormat);
51*aef9bcd9SKiyoung Kim   int32_t status = ldacBT_init_handle_encode(
52*aef9bcd9SKiyoung Kim       mHandleLdacBt, kLdacBtRequiredMtu, mFdp.PickValueInArray(kEqmidValue),
53*aef9bcd9SKiyoung Kim       mChannel, mFormat, mFdp.PickValueInArray(kSamplingFrequency));
54*aef9bcd9SKiyoung Kim   if (!status) {
55*aef9bcd9SKiyoung Kim     return true;
56*aef9bcd9SKiyoung Kim   }
57*aef9bcd9SKiyoung Kim   return false;
58*aef9bcd9SKiyoung Kim }
59*aef9bcd9SKiyoung Kim 
encodeFrames(const uint8_t * data,size_t size)60*aef9bcd9SKiyoung Kim void Codec::encodeFrames(const uint8_t *data, size_t size) {
61*aef9bcd9SKiyoung Kim   int32_t pcmUsed, streamSize, frameNum;
62*aef9bcd9SKiyoung Kim   unsigned char pStream[kOutputSize];
63*aef9bcd9SKiyoung Kim   int32_t ch, wl, frameSize;
64*aef9bcd9SKiyoung Kim   ch = (mChannel == LDAC_CCI_MONO) ? kMinChValue : kMaxChValue;
65*aef9bcd9SKiyoung Kim   wl = mFormat > kMaxWlValue ? kMaxWlValue : mFormat;
66*aef9bcd9SKiyoung Kim   frameSize = LDACBT_ENC_LSU * ch * wl;
67*aef9bcd9SKiyoung Kim   std::vector<uint8_t> tmpData(frameSize);
68*aef9bcd9SKiyoung Kim   uint8_t *readPointer = const_cast<uint8_t *>(data);
69*aef9bcd9SKiyoung Kim   while (size > 0) {
70*aef9bcd9SKiyoung Kim     if (size < frameSize) {
71*aef9bcd9SKiyoung Kim       memcpy(tmpData.data(), data, size);
72*aef9bcd9SKiyoung Kim       size = frameSize;
73*aef9bcd9SKiyoung Kim       readPointer = tmpData.data();
74*aef9bcd9SKiyoung Kim     }
75*aef9bcd9SKiyoung Kim     ldacBT_encode(mHandleLdacBt, readPointer, &pcmUsed, pStream, &streamSize,
76*aef9bcd9SKiyoung Kim                   &frameNum);
77*aef9bcd9SKiyoung Kim     readPointer += frameSize;
78*aef9bcd9SKiyoung Kim     size -= frameSize;
79*aef9bcd9SKiyoung Kim   }
80*aef9bcd9SKiyoung Kim }
81*aef9bcd9SKiyoung Kim 
getSamplingFrequeny()82*aef9bcd9SKiyoung Kim void Codec::getSamplingFrequeny() { ldacBT_get_sampling_freq(mHandleLdacBt); }
83*aef9bcd9SKiyoung Kim 
getBitrate()84*aef9bcd9SKiyoung Kim void Codec::getBitrate() { ldacBT_get_bitrate(mHandleLdacBt); }
85*aef9bcd9SKiyoung Kim 
getVersion()86*aef9bcd9SKiyoung Kim void Codec::getVersion() { ldacBT_get_version(); }
87*aef9bcd9SKiyoung Kim 
deInitEncoder()88*aef9bcd9SKiyoung Kim void Codec::deInitEncoder() {
89*aef9bcd9SKiyoung Kim   ldacBT_close_handle(mHandleLdacBt);
90*aef9bcd9SKiyoung Kim   ldacBT_free_handle(mHandleLdacBt);
91*aef9bcd9SKiyoung Kim }
92*aef9bcd9SKiyoung Kim 
LLVMFuzzerTestOneInput(const uint8_t * buf,size_t size)93*aef9bcd9SKiyoung Kim extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t size) {
94*aef9bcd9SKiyoung Kim   Codec codec(buf, size);
95*aef9bcd9SKiyoung Kim   /* initEncoder() initializes mHandleLdacBt and is supposed to be called before
96*aef9bcd9SKiyoung Kim      encoding begins. Hence initEncoder() is not included in the lambda
97*aef9bcd9SKiyoung Kim      construct. */
98*aef9bcd9SKiyoung Kim   if (codec.initEncoder()) {
99*aef9bcd9SKiyoung Kim     while (codec.mFdp.remaining_bytes() > 0) {
100*aef9bcd9SKiyoung Kim       auto executeFunction =
101*aef9bcd9SKiyoung Kim           codec.mFdp.PickValueInArray<const std::function<void()>>({
102*aef9bcd9SKiyoung Kim               [&]() { codec.encodeFrames(buf, size); },
103*aef9bcd9SKiyoung Kim               [&]() { codec.getSamplingFrequeny(); },
104*aef9bcd9SKiyoung Kim               [&]() { codec.getBitrate(); },
105*aef9bcd9SKiyoung Kim               [&]() { codec.getVersion(); },
106*aef9bcd9SKiyoung Kim           });
107*aef9bcd9SKiyoung Kim       executeFunction();
108*aef9bcd9SKiyoung Kim     }
109*aef9bcd9SKiyoung Kim   }
110*aef9bcd9SKiyoung Kim   return 0;
111*aef9bcd9SKiyoung Kim }
112