1 /*
2  *  Copyright (C) 2005-2021 Team Kodi (https://kodi.tv)
3  *
4  *  SPDX-License-Identifier: GPL-2.0-or-later
5  *  See LICENSE.md for more information.
6  */
7 
8 #include "CCE.h"
9 
10 #include "../BitStream.h"
11 #include "../huffman/Decoder.h"
12 #include "ICS.h"
13 #include "ICSInfo.h"
14 
15 using namespace aac;
16 using namespace aac::elements;
17 
Decode(BitStream & stream,int profile,int sampleFrequencyIndex)18 void CCE::Decode(BitStream& stream, int profile, int sampleFrequencyIndex)
19 {
20   // 4 bits elem id
21   stream.SkipBits(4);
22 
23   int couplingPoint = 2 * stream.ReadBit(); // ind sw cce flag
24   const int coupledCount = stream.ReadBits(3); // num coupled elements
25 
26   int gainCount = 0;
27   for (int i = 0; i <= coupledCount; ++i)
28   {
29     gainCount++;
30     const bool channelPair = stream.ReadBool();
31 
32     // 4 bits cc target is cpe
33     stream.SkipBits(4);
34 
35     if (channelPair)
36     {
37       const int chSelect = stream.ReadBits(2);
38       if (chSelect == 3)
39         gainCount++;
40     }
41   }
42 
43   couplingPoint += stream.ReadBit(); // cc domain
44   couplingPoint |= (couplingPoint >> 1);
45 
46   // 1 bit gain element sign, 2 bits gain element scale
47   stream.SkipBits(3);
48 
49   ICS ics;
50   ics.Decode(false, stream, profile, sampleFrequencyIndex);
51 
52   const int windowGroupCount = ics.GetInfo().GetWindowGroupCount();
53   const int maxSFB = ics.GetInfo().GetMaxSFB();
54   const int* sfbCB = ics.GetSfbCB();
55 
56   for (int i = 0; i < gainCount; ++i)
57   {
58     int cge = 1;
59 
60     if (i > 0)
61     {
62       cge = couplingPoint == 2 ? 1 : stream.ReadBit();
63       if (cge != 0)
64         huffman::Decoder::DecodeScaleFactor(stream);
65     }
66 
67     if (couplingPoint != 2)
68     {
69       for (int g = 0; g < windowGroupCount; ++g)
70       {
71         for (int sfb = 0; sfb < maxSFB; ++sfb)
72         {
73           if (sfbCB[sfb] != huffman::ZERO_HCB)
74           {
75             if (cge == 0)
76               huffman::Decoder::DecodeScaleFactor(stream);
77           }
78         }
79       }
80     }
81   }
82 }
83