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.
9 #include "AEBitstreamPacker.h"
11 #include "AEPackIEC61937.h"
12 #include "AEStreamInfo.h"
13 #include "utils/log.h"
22 constexpr auto BURST_HEADER_SIZE
= 8;
23 constexpr auto EAC3_MAX_BURST_PAYLOAD_SIZE
= 24576 - BURST_HEADER_SIZE
;
26 CAEBitstreamPacker::CAEBitstreamPacker()
31 CAEBitstreamPacker::~CAEBitstreamPacker()
35 void CAEBitstreamPacker::Pack(CAEStreamInfo
&info
, uint8_t* data
, int size
)
40 case CAEStreamInfo::STREAM_TYPE_TRUEHD
:
41 m_dataSize
= CAEPackIEC61937::PackTrueHD(data
+ IEC61937_DATA_OFFSET
,
42 size
- IEC61937_DATA_OFFSET
, m_packedBuffer
);
45 case CAEStreamInfo::STREAM_TYPE_DTSHD
:
46 case CAEStreamInfo::STREAM_TYPE_DTSHD_MA
:
47 PackDTSHD (info
, data
, size
);
50 case CAEStreamInfo::STREAM_TYPE_AC3
:
51 m_dataSize
= CAEPackIEC61937::PackAC3(data
, size
, m_packedBuffer
);
54 case CAEStreamInfo::STREAM_TYPE_EAC3
:
55 PackEAC3 (info
, data
, size
);
58 case CAEStreamInfo::STREAM_TYPE_DTSHD_CORE
:
59 case CAEStreamInfo::STREAM_TYPE_DTS_512
:
60 m_dataSize
= CAEPackIEC61937::PackDTS_512(data
, size
, m_packedBuffer
, info
.m_dataIsLE
);
63 case CAEStreamInfo::STREAM_TYPE_DTS_1024
:
64 m_dataSize
= CAEPackIEC61937::PackDTS_1024(data
, size
, m_packedBuffer
, info
.m_dataIsLE
);
67 case CAEStreamInfo::STREAM_TYPE_DTS_2048
:
68 m_dataSize
= CAEPackIEC61937::PackDTS_2048(data
, size
, m_packedBuffer
, info
.m_dataIsLE
);
72 CLog::Log(LOGERROR
, "CAEBitstreamPacker::Pack - no pack function");
76 bool CAEBitstreamPacker::PackPause(CAEStreamInfo
&info
, unsigned int millis
, bool iecBursts
)
79 if (m_pauseDuration
== millis
)
84 case CAEStreamInfo::STREAM_TYPE_TRUEHD
:
85 case CAEStreamInfo::STREAM_TYPE_EAC3
:
86 m_dataSize
= CAEPackIEC61937::PackPause(m_packedBuffer
, millis
, GetOutputChannelMap(info
).Count() * 2, GetOutputRate(info
), 4, info
.m_sampleRate
);
87 m_pauseDuration
= millis
;
90 case CAEStreamInfo::STREAM_TYPE_AC3
:
91 case CAEStreamInfo::STREAM_TYPE_DTSHD
:
92 case CAEStreamInfo::STREAM_TYPE_DTSHD_MA
:
93 case CAEStreamInfo::STREAM_TYPE_DTSHD_CORE
:
94 case CAEStreamInfo::STREAM_TYPE_DTS_512
:
95 case CAEStreamInfo::STREAM_TYPE_DTS_1024
:
96 case CAEStreamInfo::STREAM_TYPE_DTS_2048
:
97 m_dataSize
= CAEPackIEC61937::PackPause(m_packedBuffer
, millis
, GetOutputChannelMap(info
).Count() * 2, GetOutputRate(info
), 3, info
.m_sampleRate
);
98 m_pauseDuration
= millis
;
102 CLog::Log(LOGERROR
, "CAEBitstreamPacker::Pack - no pack function");
107 memset(m_packedBuffer
, 0, m_dataSize
);
113 unsigned int CAEBitstreamPacker::GetSize() const
118 uint8_t* CAEBitstreamPacker::GetBuffer()
120 return m_packedBuffer
;
123 void CAEBitstreamPacker::Reset()
127 m_packedBuffer
[0] = 0;
130 void CAEBitstreamPacker::PackDTSHD(CAEStreamInfo
&info
, uint8_t* data
, int size
)
132 static const uint8_t dtshd_start_code
[10] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe };
133 unsigned int dataSize
= sizeof(dtshd_start_code
) + 2 + size
;
135 if (dataSize
> m_dtsHDSize
)
137 m_dtsHDSize
= dataSize
;
138 m_dtsHD
.resize(dataSize
);
139 memcpy(m_dtsHD
.data(), dtshd_start_code
, sizeof(dtshd_start_code
));
142 m_dtsHD
[sizeof(dtshd_start_code
) + 0] = ((uint16_t)size
& 0xFF00) >> 8;
143 m_dtsHD
[sizeof(dtshd_start_code
) + 1] = ((uint16_t)size
& 0x00FF);
144 memcpy(m_dtsHD
.data() + sizeof(dtshd_start_code
) + 2, data
, size
);
147 CAEPackIEC61937::PackDTSHD(m_dtsHD
.data(), dataSize
, m_packedBuffer
, info
.m_dtsPeriod
);
150 void CAEBitstreamPacker::PackEAC3(CAEStreamInfo
&info
, uint8_t* data
, int size
)
152 unsigned int framesPerBurst
= info
.m_repeat
;
154 if (m_eac3FramesPerBurst
!= framesPerBurst
)
156 /* switched streams, discard partial burst */
158 m_eac3FramesPerBurst
= framesPerBurst
;
161 if (m_eac3FramesPerBurst
== 1)
163 /* simple case, just pass through */
164 m_dataSize
= CAEPackIEC61937::PackEAC3(data
, size
, m_packedBuffer
);
168 /* multiple frames needed to achieve 6 blocks as required by IEC 61937-3:2007 */
170 if (m_eac3
.size() == 0)
171 m_eac3
.resize(EAC3_MAX_BURST_PAYLOAD_SIZE
);
173 unsigned int newsize
= m_eac3Size
+ size
;
174 bool overrun
= newsize
> EAC3_MAX_BURST_PAYLOAD_SIZE
;
178 memcpy(m_eac3
.data() + m_eac3Size
, data
, size
);
179 m_eac3Size
= newsize
;
183 if (m_eac3FramesCount
>= m_eac3FramesPerBurst
|| overrun
)
185 m_dataSize
= CAEPackIEC61937::PackEAC3(m_eac3
.data(), m_eac3Size
, m_packedBuffer
);
187 m_eac3FramesCount
= 0;
192 unsigned int CAEBitstreamPacker::GetOutputRate(const CAEStreamInfo
& info
)
197 case CAEStreamInfo::STREAM_TYPE_AC3
:
198 rate
= info
.m_sampleRate
;
200 case CAEStreamInfo::STREAM_TYPE_EAC3
:
201 rate
= info
.m_sampleRate
* 4;
203 case CAEStreamInfo::STREAM_TYPE_TRUEHD
:
204 if (info
.m_sampleRate
== 48000 ||
205 info
.m_sampleRate
== 96000 ||
206 info
.m_sampleRate
== 192000)
211 case CAEStreamInfo::STREAM_TYPE_DTS_512
:
212 case CAEStreamInfo::STREAM_TYPE_DTS_1024
:
213 case CAEStreamInfo::STREAM_TYPE_DTS_2048
:
214 case CAEStreamInfo::STREAM_TYPE_DTSHD_CORE
:
215 rate
= info
.m_sampleRate
;
217 case CAEStreamInfo::STREAM_TYPE_DTSHD
:
218 case CAEStreamInfo::STREAM_TYPE_DTSHD_MA
:
228 CAEChannelInfo
CAEBitstreamPacker::GetOutputChannelMap(const CAEStreamInfo
& info
)
233 case CAEStreamInfo::STREAM_TYPE_AC3
:
234 case CAEStreamInfo::STREAM_TYPE_EAC3
:
235 case CAEStreamInfo::STREAM_TYPE_DTS_512
:
236 case CAEStreamInfo::STREAM_TYPE_DTS_1024
:
237 case CAEStreamInfo::STREAM_TYPE_DTS_2048
:
238 case CAEStreamInfo::STREAM_TYPE_DTSHD_CORE
:
239 case CAEStreamInfo::STREAM_TYPE_DTSHD
:
243 case CAEStreamInfo::STREAM_TYPE_TRUEHD
:
244 case CAEStreamInfo::STREAM_TYPE_DTSHD_MA
:
252 CAEChannelInfo channelMap
;
253 for (int i
=0; i
<channels
; i
++)
255 channelMap
+= AE_CH_RAW
;