Merge pull request #1129 from jmarshallnz/remove_smb_auth_details_in_add_source
[vuplus_xbmc] / xbmc / cores / AudioEngine / Utils / AEBitstreamPacker.cpp
1 /*
2  *      Copyright (C) 2010-2012 Team XBMC
3  *      http://www.xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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
19  *
20  */
21
22 #include "AEBitstreamPacker.h"
23 #include "AEPackIEC61937.h"
24 #include "AEStreamInfo.h"
25 #include <stdint.h>
26 #include <stddef.h>
27 #include <string.h>
28
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
33
34 CAEBitstreamPacker::CAEBitstreamPacker() :
35   m_trueHD   (NULL),
36   m_trueHDPos(0),
37   m_dtsHD    (NULL),
38   m_dtsHDSize(0),
39   m_dataSize (0)
40 {
41 }
42
43 CAEBitstreamPacker::~CAEBitstreamPacker()
44 {
45   delete[] m_trueHD;
46   delete[] m_dtsHD;
47 }
48
49 void CAEBitstreamPacker::Pack(CAEStreamInfo &info, uint8_t* data, int size)
50 {
51   switch (info.GetDataType())
52   {
53     case CAEStreamInfo::STREAM_TYPE_TRUEHD:
54       PackTrueHD(info, data, size);
55       break;
56
57     case CAEStreamInfo::STREAM_TYPE_DTSHD:
58       PackDTSHD (info, data, size);
59       break;
60
61     case CAEStreamInfo::STREAM_TYPE_DTS_512:
62       m_dataSize = CAEPackIEC61937::PackDTS_512(data, size, m_packedBuffer, info.IsLittleEndian());
63       break;
64
65     case CAEStreamInfo::STREAM_TYPE_DTS_1024:
66       m_dataSize = CAEPackIEC61937::PackDTS_1024(data, size, m_packedBuffer, info.IsLittleEndian());
67       break;
68
69     case CAEStreamInfo::STREAM_TYPE_DTS_2048:
70       m_dataSize = CAEPackIEC61937::PackDTS_2048(data, size, m_packedBuffer, info.IsLittleEndian());
71       break;
72
73     default:
74       /* pack the data into an IEC61937 frame */
75       CAEPackIEC61937::PackFunc pack = info.GetPackFunc();
76       if (pack)
77         m_dataSize = pack(data, size, m_packedBuffer);
78   }
79 }
80
81 unsigned int CAEBitstreamPacker::GetSize()
82 {
83   return m_dataSize;
84 }
85
86 uint8_t* CAEBitstreamPacker::GetBuffer()
87 {
88   m_dataSize = 0;
89   return m_packedBuffer;
90 }
91
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)
94 {
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 };
99
100   /* create the buffer if it doesnt already exist */
101   if (!m_trueHD)
102   {
103     m_trueHD    = new uint8_t[MAT_FRAME_SIZE];
104     m_trueHDPos = 0;
105   }
106
107   /* setup the frame for the data */
108   if (m_trueHDPos == 0)
109   {
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));
114   }
115
116   size_t offset;
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;
121   else
122     offset = (m_trueHDPos * TRUEHD_FRAME_OFFSET) - BURST_HEADER_SIZE;
123
124   memcpy(m_trueHD + offset, data, size);
125
126   /* if we have a full frame */
127   if (++m_trueHDPos == 24)
128   {
129     m_trueHDPos = 0;
130     m_dataSize  = CAEPackIEC61937::PackTrueHD(m_trueHD, MAT_FRAME_SIZE, m_packedBuffer);
131   }
132 }
133
134 void CAEBitstreamPacker::PackDTSHD(CAEStreamInfo &info, uint8_t* data, int size)
135 {
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;
138
139   if (dataSize > m_dtsHDSize)
140   {
141     delete[] m_dtsHD;
142     m_dtsHDSize = dataSize;
143     m_dtsHD     = new uint8_t[dataSize];
144     memcpy(m_dtsHD, dtshd_start_code, sizeof(dtshd_start_code));
145   }
146
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);
150
151   m_dataSize = CAEPackIEC61937::PackDTSHD(m_dtsHD, dataSize, m_packedBuffer, info.GetDTSPeriod());
152 }
153