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 "DSE.h" 9 10 #include "../BitStream.h" 11 12 #include <cstring> 13 #include <exception> 14 15 using namespace aac; 16 using namespace aac::elements; 17 Decode(BitStream & stream)18void DSE::Decode(BitStream& stream) 19 { 20 // 4 bits elem id 21 stream.SkipBits(4); 22 23 const bool byteAlign = stream.ReadBool(); 24 int count = stream.ReadBits(8); 25 if (count == 255) 26 count += stream.ReadBits(8); 27 28 if (byteAlign) 29 stream.ByteAlign(); 30 31 stream.SkipBits(8 * count); 32 } 33 DecodeRDS(BitStream & stream,uint8_t * & rdsdata)34uint8_t DSE::DecodeRDS(BitStream& stream, uint8_t*& rdsdata) 35 { 36 // 4 bits elem id 37 stream.SkipBits(4); 38 39 const bool byteAlign = stream.ReadBool(); 40 int count = stream.ReadBits(8); 41 if (count == 255) 42 count += stream.ReadBits(8); 43 44 if (byteAlign) 45 stream.ByteAlign(); 46 47 static constexpr int BUFFER_SIZE = 65536; 48 static uint8_t buffer[BUFFER_SIZE]; 49 static int bufferpos = 0; 50 51 uint8_t ret = 0; 52 53 if (count > BUFFER_SIZE) 54 { 55 // data package too large! turn over with next package. 56 stream.SkipBits(8 * count); 57 bufferpos = 0; 58 return ret; 59 } 60 61 if (bufferpos + count > BUFFER_SIZE) 62 { 63 // buffer overflow! turn over now. 64 bufferpos = 0; 65 } 66 67 try 68 { 69 // collect data 70 for (int i = 0; i < count; ++i) 71 { 72 buffer[bufferpos + i] = static_cast<uint8_t>(stream.ReadBits(8)); 73 } 74 bufferpos += count; 75 } 76 catch (std::exception&) 77 { 78 // cleanup and rethrow 79 bufferpos = 0; 80 throw; 81 } 82 83 if (bufferpos > 0 && buffer[bufferpos - 1] == 0xFF) 84 { 85 if (buffer[0] == 0xFE) 86 { 87 // data package is complete. deliver it. 88 rdsdata = new uint8_t[bufferpos]; // Note: caller has to delete the data array 89 std::memcpy(rdsdata, buffer, bufferpos); 90 ret = bufferpos; 91 } 92 bufferpos = 0; 93 } 94 95 return ret; 96 } 97