[videodb] remove unused seasons table from episode_view
[xbmc.git] / xbmc / cores / AudioEngine / Utils / AEPackIEC61937.cpp
blob43bfbf3c735c8df91b12ddb76d31f771fe811fc8
1 /*
2 * Copyright (C) 2010-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "AEPackIEC61937.h"
11 #include <cassert>
12 #include <string.h>
14 #define IEC61937_PREAMBLE1 0xF872
15 #define IEC61937_PREAMBLE2 0x4E1F
17 inline void SwapEndian(uint16_t *dst, uint16_t *src, unsigned int size)
19 for (unsigned int i = 0; i < size; ++i, ++dst, ++src)
20 *dst = ((*src & 0xFF00) >> 8) | ((*src & 0x00FF) << 8);
23 int CAEPackIEC61937::PackAC3(uint8_t *data, unsigned int size, uint8_t *dest)
25 assert(size <= OUT_FRAMESTOBYTES(AC3_FRAME_SIZE));
26 struct IEC61937Packet *packet = (struct IEC61937Packet*)dest;
28 packet->m_preamble1 = IEC61937_PREAMBLE1;
29 packet->m_preamble2 = IEC61937_PREAMBLE2;
30 packet->m_length = size << 3;
32 if (data == NULL)
33 data = packet->m_data;
34 #ifdef __BIG_ENDIAN__
35 else
36 memcpy(packet->m_data, data, size);
37 #else
39 int bitstream_mode = data[5] & 0x7;
40 packet->m_type = IEC61937_TYPE_AC3 | (bitstream_mode << 8);
42 size += size & 0x1;
43 SwapEndian((uint16_t*)packet->m_data, (uint16_t*)data, size >> 1);
44 #endif
46 memset(packet->m_data + size, 0, OUT_FRAMESTOBYTES(AC3_FRAME_SIZE) - IEC61937_DATA_OFFSET - size);
47 return OUT_FRAMESTOBYTES(AC3_FRAME_SIZE);
50 int CAEPackIEC61937::PackEAC3(uint8_t *data, unsigned int size, uint8_t *dest)
52 assert(size <= OUT_FRAMESTOBYTES(EAC3_FRAME_SIZE));
53 struct IEC61937Packet *packet = (struct IEC61937Packet*)dest;
55 packet->m_preamble1 = IEC61937_PREAMBLE1;
56 packet->m_preamble2 = IEC61937_PREAMBLE2;
57 packet->m_type = IEC61937_TYPE_EAC3;
58 packet->m_length = size;
60 if (data == NULL)
61 data = packet->m_data;
62 #ifdef __BIG_ENDIAN__
63 else
64 memcpy(packet->m_data, data, size);
65 #else
66 size += size & 0x1;
67 SwapEndian((uint16_t*)packet->m_data, (uint16_t*)data, size >> 1);
68 #endif
70 memset(packet->m_data + size, 0, OUT_FRAMESTOBYTES(EAC3_FRAME_SIZE) - IEC61937_DATA_OFFSET - size);
71 return OUT_FRAMESTOBYTES(EAC3_FRAME_SIZE);
74 int CAEPackIEC61937::PackDTS_512(uint8_t *data, unsigned int size, uint8_t *dest, bool littleEndian)
76 return PackDTS(data, size, dest, littleEndian, OUT_FRAMESTOBYTES(DTS1_FRAME_SIZE), IEC61937_TYPE_DTS1);
79 int CAEPackIEC61937::PackDTS_1024(uint8_t *data, unsigned int size, uint8_t *dest, bool littleEndian)
81 return PackDTS(data, size, dest, littleEndian, OUT_FRAMESTOBYTES(DTS2_FRAME_SIZE), IEC61937_TYPE_DTS2);
84 int CAEPackIEC61937::PackDTS_2048(uint8_t *data, unsigned int size, uint8_t *dest, bool littleEndian)
86 return PackDTS(data, size, dest, littleEndian, OUT_FRAMESTOBYTES(DTS3_FRAME_SIZE), IEC61937_TYPE_DTS3);
89 int CAEPackIEC61937::PackTrueHD(const uint8_t* data, unsigned int size, uint8_t* dest)
91 if (size == 0)
92 return OUT_FRAMESTOBYTES(TRUEHD_FRAME_SIZE);
94 assert(size <= OUT_FRAMESTOBYTES(TRUEHD_FRAME_SIZE));
95 struct IEC61937Packet *packet = (struct IEC61937Packet*)dest;
96 packet->m_preamble1 = IEC61937_PREAMBLE1;
97 packet->m_preamble2 = IEC61937_PREAMBLE2;
98 packet->m_type = IEC61937_TYPE_TRUEHD;
99 packet->m_length = 61424;
101 if (data == NULL)
102 data = packet->m_data;
103 #ifdef __BIG_ENDIAN__
104 else
105 memcpy(packet->m_data, data, size);
106 #else
107 size += size & 0x1;
108 SwapEndian((uint16_t*)packet->m_data, (uint16_t*)data, size >> 1);
109 #endif
111 memset(packet->m_data + size, 0, OUT_FRAMESTOBYTES(TRUEHD_FRAME_SIZE) - IEC61937_DATA_OFFSET - size);
112 return OUT_FRAMESTOBYTES(TRUEHD_FRAME_SIZE);
115 int CAEPackIEC61937::PackDTSHD(uint8_t *data, unsigned int size, uint8_t *dest, unsigned int period)
117 unsigned int subtype;
118 switch (period)
120 case 512: subtype = 0; break;
121 case 1024: subtype = 1; break;
122 case 2048: subtype = 2; break;
123 case 4096: subtype = 3; break;
124 case 8192: subtype = 4; break;
125 case 16384: subtype = 5; break;
127 default:
128 return 0;
131 struct IEC61937Packet *packet = (struct IEC61937Packet*)dest;
132 packet->m_preamble1 = IEC61937_PREAMBLE1;
133 packet->m_preamble2 = IEC61937_PREAMBLE2;
134 packet->m_type = IEC61937_TYPE_DTSHD | (subtype << 8);
136 /* Align so that (length_code & 0xf) == 0x8. This is reportedly needed
137 * with some receivers, but the exact requirement is unconfirmed. */
138 packet->m_length = ((size + 0x17) &~ 0x0f) - 0x08;
140 if (data == NULL)
141 data = packet->m_data;
142 #ifdef __BIG_ENDIAN__
143 else
144 memcpy(packet->m_data, data, size);
145 #else
146 size += size & 0x1;
147 SwapEndian((uint16_t*)packet->m_data, (uint16_t*)data, size >> 1);
148 #endif
150 unsigned int burstsize = period << 2;
151 memset(packet->m_data + size, 0, burstsize - IEC61937_DATA_OFFSET - size);
152 return burstsize;
155 int CAEPackIEC61937::PackDTS(uint8_t *data, unsigned int size, uint8_t *dest, bool littleEndian,
156 unsigned int frameSize, uint16_t type)
158 assert(size <= frameSize);
160 /* BE is the standard endianness, byteswap needed if LE */
161 bool byteSwapNeeded = littleEndian;
163 #ifndef __BIG_ENDIAN__
164 /* on LE systems we want LE output, byteswap needed */
165 byteSwapNeeded ^= true;
166 #endif
168 struct IEC61937Packet *packet = (struct IEC61937Packet*)dest;
169 uint8_t *dataTo;
171 if (size == frameSize)
173 /* No packing possible or needed, DTS stream is suitable for direct output */
174 dataTo = dest;
176 else if (size <= frameSize - IEC61937_DATA_OFFSET)
178 /* Fits to IEC61937, perform packing */
179 packet->m_preamble1 = IEC61937_PREAMBLE1;
180 packet->m_preamble2 = IEC61937_PREAMBLE2;
181 packet->m_type = type;
182 packet->m_length = size << 3;
184 dataTo = packet->m_data;
186 else
188 /* Stream is unsuitable for both packing and direct output */
189 return 0;
192 if (data == NULL)
193 data = dataTo;
194 else if (!byteSwapNeeded)
195 memcpy(dataTo, data, size);
197 if (byteSwapNeeded)
199 size += size & 0x1;
200 SwapEndian((uint16_t*)dataTo, (uint16_t*)data, size >> 1);
203 if (size != frameSize)
204 memset(packet->m_data + size, 0, frameSize - IEC61937_DATA_OFFSET - size);
206 return frameSize;
209 int CAEPackIEC61937::PackPause(uint8_t *dest, unsigned int millis, unsigned int framesize, unsigned int samplerate, unsigned int rep_period, unsigned int encodedRate)
211 int periodInBytes = rep_period * framesize;
212 double periodInTime = (double)rep_period / samplerate * 1000;
213 int periodsNeeded = millis / periodInTime;
214 int maxPeriods = MAX_IEC61937_PACKET / periodInBytes;
215 if (periodsNeeded > maxPeriods)
216 periodsNeeded = maxPeriods;
217 uint16_t gap = encodedRate * millis / 1000;
219 struct IEC61937Packet *packet = (struct IEC61937Packet*)dest;
220 packet->m_preamble1 = IEC61937_PREAMBLE1;
221 packet->m_preamble2 = IEC61937_PREAMBLE2;
222 packet->m_type = 3;
223 packet->m_length = 32;
224 memset(packet->m_data, 0, periodInBytes - 8);
226 for (int i=1; i<periodsNeeded; i++)
228 memcpy(dest+i*periodInBytes, dest, periodInBytes);
231 uint16_t *gapPtr = reinterpret_cast<uint16_t*>(packet->m_data);
232 *gapPtr = gap;
234 return periodsNeeded * periodInBytes;