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