2 * Copyright (C) 2010-2012 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #include "AEBitstreamPacker.h"
23 #include "AEPackIEC61937.h"
24 #include "AEStreamInfo.h"
29 #define BURST_HEADER_SIZE 8
30 #define TRUEHD_FRAME_OFFSET 2560
31 #define MAT_MIDDLE_CODE_OFFSET -4
32 #define MAT_FRAME_SIZE 61424
34 CAEBitstreamPacker::CAEBitstreamPacker() :
43 CAEBitstreamPacker::~CAEBitstreamPacker()
49 void CAEBitstreamPacker::Pack(CAEStreamInfo &info, uint8_t* data, int size)
51 switch (info.GetDataType())
53 case CAEStreamInfo::STREAM_TYPE_TRUEHD:
54 PackTrueHD(info, data, size);
57 case CAEStreamInfo::STREAM_TYPE_DTSHD:
58 PackDTSHD (info, data, size);
61 case CAEStreamInfo::STREAM_TYPE_DTS_512:
62 m_dataSize = CAEPackIEC61937::PackDTS_512(data, size, m_packedBuffer, info.IsLittleEndian());
65 case CAEStreamInfo::STREAM_TYPE_DTS_1024:
66 m_dataSize = CAEPackIEC61937::PackDTS_1024(data, size, m_packedBuffer, info.IsLittleEndian());
69 case CAEStreamInfo::STREAM_TYPE_DTS_2048:
70 m_dataSize = CAEPackIEC61937::PackDTS_2048(data, size, m_packedBuffer, info.IsLittleEndian());
74 /* pack the data into an IEC61937 frame */
75 CAEPackIEC61937::PackFunc pack = info.GetPackFunc();
77 m_dataSize = pack(data, size, m_packedBuffer);
81 unsigned int CAEBitstreamPacker::GetSize()
86 uint8_t* CAEBitstreamPacker::GetBuffer()
89 return m_packedBuffer;
92 /* we need to pack 24 TrueHD audio units into the unknown MAT format before packing into IEC61937 */
93 void CAEBitstreamPacker::PackTrueHD(CAEStreamInfo &info, uint8_t* data, int size)
95 /* magic MAT format values, meaning is unknown at this point */
96 static const uint8_t mat_start_code [20] = { 0x07, 0x9E, 0x00, 0x03, 0x84, 0x01, 0x01, 0x01, 0x80, 0x00, 0x56, 0xA5, 0x3B, 0xF4, 0x81, 0x83, 0x49, 0x80, 0x77, 0xE0 };
97 static const uint8_t mat_middle_code[12] = { 0xC3, 0xC1, 0x42, 0x49, 0x3B, 0xFA, 0x82, 0x83, 0x49, 0x80, 0x77, 0xE0 };
98 static const uint8_t mat_end_code [16] = { 0xC3, 0xC2, 0xC0, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x11 };
100 /* create the buffer if it doesnt already exist */
103 m_trueHD = new uint8_t[MAT_FRAME_SIZE];
107 /* setup the frame for the data */
108 if (m_trueHDPos == 0)
110 memset(m_trueHD, 0, MAT_FRAME_SIZE);
111 memcpy(m_trueHD, mat_start_code, sizeof(mat_start_code));
112 memcpy(m_trueHD + (12 * TRUEHD_FRAME_OFFSET) - BURST_HEADER_SIZE + MAT_MIDDLE_CODE_OFFSET, mat_middle_code, sizeof(mat_middle_code));
113 memcpy(m_trueHD + MAT_FRAME_SIZE - sizeof(mat_end_code), mat_end_code, sizeof(mat_end_code));
117 if (m_trueHDPos == 0 )
118 offset = (m_trueHDPos * TRUEHD_FRAME_OFFSET) + sizeof(mat_start_code);
119 else if (m_trueHDPos == 12)
120 offset = (m_trueHDPos * TRUEHD_FRAME_OFFSET) + sizeof(mat_middle_code) - BURST_HEADER_SIZE + MAT_MIDDLE_CODE_OFFSET;
122 offset = (m_trueHDPos * TRUEHD_FRAME_OFFSET) - BURST_HEADER_SIZE;
124 memcpy(m_trueHD + offset, data, size);
126 /* if we have a full frame */
127 if (++m_trueHDPos == 24)
130 m_dataSize = CAEPackIEC61937::PackTrueHD(m_trueHD, MAT_FRAME_SIZE, m_packedBuffer);
134 void CAEBitstreamPacker::PackDTSHD(CAEStreamInfo &info, uint8_t* data, int size)
136 static const uint8_t dtshd_start_code[10] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe };
137 unsigned int dataSize = sizeof(dtshd_start_code) + 2 + size;
139 if (dataSize > m_dtsHDSize)
142 m_dtsHDSize = dataSize;
143 m_dtsHD = new uint8_t[dataSize];
144 memcpy(m_dtsHD, dtshd_start_code, sizeof(dtshd_start_code));
147 m_dtsHD[sizeof(dtshd_start_code) + 0] = ((uint16_t)size & 0xFF00) >> 8;
148 m_dtsHD[sizeof(dtshd_start_code) + 1] = ((uint16_t)size & 0x00FF);
149 memcpy(m_dtsHD + sizeof(dtshd_start_code) + 2, data, size);
151 m_dataSize = CAEPackIEC61937::PackDTSHD(m_dtsHD, dataSize, m_packedBuffer, info.GetDTSPeriod());