strip added smb:// shares of their user/pass when adding, and instead store that...
[vuplus_xbmc] / xbmc / cores / AudioEngine / Utils / AEStreamInfo.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 "AEStreamInfo.h"
23
24 #define IEC61937_PREAMBLE1 0xF872
25 #define IEC61937_PREAMBLE2 0x4E1F
26 #define DTS_PREAMBLE_14BE  0x1FFFE800
27 #define DTS_PREAMBLE_14LE  0xFF1F00E8
28 #define DTS_PREAMBLE_16BE  0x7FFE8001
29 #define DTS_PREAMBLE_16LE  0xFE7F0180
30 #define DTS_PREAMBLE_HD    0x64582025
31 #define DTS_SFREQ_COUNT    16
32 #define MAX_EAC3_BLOCKS    6
33
34 static enum AEChannel OutputMaps[2][9] = {
35   {AE_CH_RAW, AE_CH_RAW, AE_CH_NULL},
36   {AE_CH_RAW, AE_CH_RAW, AE_CH_RAW, AE_CH_RAW, AE_CH_RAW, AE_CH_RAW, AE_CH_RAW, AE_CH_RAW, AE_CH_NULL}
37 };
38
39 static const uint16_t AC3Bitrates   [] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640};
40 static const uint16_t AC3FSCod      [] = {48000, 44100, 32000, 0};
41 static const uint8_t  AC3BlkCod     [] = {1, 2, 3, 6};
42 static const uint8_t  AC3Channels   [] = {2, 1, 2, 3, 3, 4, 4, 5};
43 static const uint8_t  DTSChannels   [] = {1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8};
44 static const uint8_t  THDChanMap    [] = {2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1};
45
46 static const uint32_t DTSSampleRates[DTS_SFREQ_COUNT] =
47 {
48   0     ,
49   8000  ,
50   16000 ,
51   32000 ,
52   64000 ,
53   128000,
54   11025 ,
55   22050 ,
56   44100 ,
57   88200 ,
58   176400,
59   12000 ,
60   24000 ,
61   48000 ,
62   96000 ,
63   192000
64 };
65
66 CAEStreamInfo::CAEStreamInfo() :
67   m_bufferSize(0),
68   m_skipBytes (0),
69   m_coreOnly  (false),
70   m_needBytes (0),
71   m_syncFunc  (&CAEStreamInfo::DetectType),
72   m_hasSync   (false),
73   m_sampleRate(0),
74   m_dtsBlocks (0),
75   m_dataType  (STREAM_TYPE_NULL),
76   m_packFunc  (NULL)
77 {
78   m_dllAvUtil.Load();
79   m_dllAvUtil.av_crc_init(m_crcTrueHD, 0, 16, 0x2D, sizeof(m_crcTrueHD));
80 }
81
82 CAEStreamInfo::~CAEStreamInfo()
83 {
84   m_dllAvUtil.Unload();
85 }
86
87 int CAEStreamInfo::AddData(uint8_t *data, unsigned int size, uint8_t **buffer/* = NULL */, unsigned int *bufferSize/* = 0 */)
88 {
89   if (size == 0)
90   {
91     if (bufferSize)
92       *bufferSize = 0;
93     return 0;
94   }
95
96   unsigned int consumed = 0;
97   if (m_skipBytes)
98   {
99     unsigned int canSkip = std::min(size, m_skipBytes);
100     unsigned int room    = sizeof(m_buffer) - m_bufferSize;
101     unsigned int copy    = std::min(room, canSkip);
102
103     memcpy(m_buffer + m_bufferSize, data, copy);
104     m_bufferSize += copy;
105     m_skipBytes  -= copy;
106
107     if (m_skipBytes)
108     {
109       if (bufferSize)
110         *bufferSize = 0;
111       return copy;
112     }
113
114     GetPacket(buffer, bufferSize);
115     return copy;
116   }
117   else
118   {
119     unsigned int offset = 0;
120     unsigned int room = sizeof(m_buffer) - m_bufferSize;
121     while(1)
122     {
123       if (!size)
124       {
125         if (bufferSize)
126           *bufferSize = 0;
127         return consumed;
128       }
129
130       unsigned int copy = std::min(room, size);
131       memcpy(m_buffer + m_bufferSize, data, copy);
132       m_bufferSize += copy;
133       consumed     += copy;
134       data         += copy;
135       size         -= copy;
136       room         -= copy;
137
138       if (m_needBytes > m_bufferSize)
139         continue;
140
141       m_needBytes = 0;
142       offset      = (this->*m_syncFunc)(m_buffer, m_bufferSize);
143
144       if (m_hasSync || m_needBytes)
145         break;
146       else
147       {
148         /* lost sync */
149         m_syncFunc = &CAEStreamInfo::DetectType;
150         m_dataType = STREAM_TYPE_NULL;
151         m_packFunc = NULL;
152         m_repeat   = 1;
153
154         /* if the buffer is full, or the offset < the buffer size */
155         if (m_bufferSize == sizeof(m_buffer) || offset < m_bufferSize)
156         {
157           m_bufferSize -= offset;
158           room         += offset;
159           memmove(m_buffer, m_buffer + offset, m_bufferSize);
160         }
161       }
162     }
163
164     /* if we got here, we acquired sync on the buffer */
165
166     /* align the buffer */
167     if (offset)
168     {
169       m_bufferSize -= offset;
170       memmove(m_buffer, m_buffer + offset, m_bufferSize);
171     }
172
173     /* bytes to skip until the next packet */
174     m_skipBytes = std::max(0, (int)m_fsize - (int)m_bufferSize);
175     if (m_skipBytes)
176     {
177       if (bufferSize)
178         *bufferSize = 0;
179       return consumed;
180     }
181
182     if (!m_needBytes)
183       GetPacket(buffer, bufferSize);
184
185     return consumed;
186   }
187 }
188
189 void CAEStreamInfo::GetPacket(uint8_t **buffer, unsigned int *bufferSize)
190 {
191   /* if the caller wants the packet */
192   if (buffer)
193   {
194     /* if it is dtsHD and we only want the core, just fetch that */
195     unsigned int size = m_fsize;
196     if (m_dataType == STREAM_TYPE_DTSHD_CORE)
197       size = m_coreSize;
198
199     /* make sure the buffer is allocated and big enough */
200     if (!*buffer || !bufferSize || *bufferSize < size)
201     {
202       delete[] *buffer;
203       *buffer = new uint8_t[size];
204     }
205
206     /* copy the data into the buffer and update the size */
207     memcpy(*buffer, m_buffer, size);
208     if (bufferSize)
209       *bufferSize = size;
210   }
211
212   /* remove the parsed data from the buffer */
213   m_bufferSize -= m_fsize;
214   memmove(m_buffer, m_buffer + m_fsize, m_bufferSize);
215   m_fsize = 0;
216   m_coreSize = 0;
217 }
218
219 /* SYNC FUNCTIONS */
220
221 /*
222   This function looks for sync words across the types in paralell, and only does an exhaustive
223   test if it finds a syncword. Once sync has been established, the relevent sync function sets
224   m_syncFunc to itself. This function will only be called again if total sync is lost, which
225   allows is to switch stream types on the fly much like a real reicever does.
226 */
227 unsigned int CAEStreamInfo::DetectType(uint8_t *data, unsigned int size)
228 {
229   unsigned int skipped  = 0;
230   unsigned int possible = 0;
231
232   while (size > 8)
233   {
234     /* if it could be DTS */
235     unsigned int header = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
236     if (header == DTS_PREAMBLE_14LE ||
237         header == DTS_PREAMBLE_14BE ||
238         header == DTS_PREAMBLE_16LE ||
239         header == DTS_PREAMBLE_16BE)
240     {
241       unsigned int skip = SyncDTS(data, size);
242       if (m_hasSync || m_needBytes)
243         return skipped + skip;
244       else
245         possible = skipped;
246     }
247
248     /* if it could be AC3 */
249     if (data[0] == 0x0b && data[1] == 0x77)
250     {
251       unsigned int skip = SyncAC3(data, size);
252       if (m_hasSync)
253         return skipped + skip;
254       else
255         possible = skipped;
256     }
257
258     /* if it could be TrueHD */
259     if (data[4] == 0xf8 && data[5] == 0x72 && data[6] == 0x6f && data[7] == 0xba)
260     {
261       unsigned int skip = SyncTrueHD(data, size);
262       if (m_hasSync)
263         return skipped + skip;
264       else
265         possible = skipped;
266     }
267
268     /* move along one byte */
269     --size;
270     ++skipped;
271     ++data;
272   }
273
274   return possible ? possible : skipped;
275 }
276
277 unsigned int CAEStreamInfo::SyncAC3(uint8_t *data, unsigned int size)
278 {
279   unsigned int skip = 0;
280
281   for (; size - skip > 7; ++skip, ++data)
282   {
283     /* search for an ac3 sync word */
284     if (data[0] != 0x0b || data[1] != 0x77)
285       continue;
286
287     uint8_t bsid  = data[5] >> 3;
288     uint8_t acmod = data[6] >> 5;
289     uint8_t lfeon;
290
291     int8_t pos = 4;
292     if ((acmod & 0x1) && (acmod != 0x1))
293       pos -= 2;
294     if (acmod & 0x4 )
295       pos -= 2;
296     if (acmod == 0x2)
297       pos -= 2;
298     if (pos < 0)
299       lfeon = (data[7] & 0x64) ? 1 : 0;
300     else
301       lfeon = ((data[6] >> pos) & 0x1) ? 1 : 0;
302
303     if (bsid > 0x11 || acmod > 8)
304       continue;
305
306     if (bsid <= 10)
307     {
308       /* Normal AC-3 */
309
310       uint8_t fscod      = data[4] >> 6;
311       uint8_t frmsizecod = data[4] & 0x3F;
312       if (fscod == 3 || frmsizecod > 37)
313         continue;
314
315       /* get the details we need to check crc1 and framesize */
316       unsigned int bitRate = AC3Bitrates[frmsizecod >> 1];
317       unsigned int framesize = 0;
318       switch (fscod)
319       {
320         case 0: framesize = bitRate * 2; break;
321         case 1: framesize = (320 * bitRate / 147 + (frmsizecod & 1 ? 1 : 0)); break;
322         case 2: framesize = bitRate * 4; break;
323       }
324
325       m_fsize = framesize << 1;
326       m_sampleRate = AC3FSCod[fscod];
327
328       /* dont do extensive testing if we have not lost sync */
329       if (m_dataType == STREAM_TYPE_AC3 && skip == 0)
330         return 0;
331
332       unsigned int crc_size;
333       /* if we have enough data, validate the entire packet, else try to validate crc2 (5/8 of the packet) */
334       if (framesize <= size - skip)
335         crc_size = framesize - 1;
336       else 
337         crc_size = (framesize >> 1) + (framesize >> 3) - 1;
338
339       if (crc_size <= size - skip)
340         if (m_dllAvUtil.av_crc(m_dllAvUtil.av_crc_get_table(AV_CRC_16_ANSI), 0, &data[2], crc_size * 2))
341           continue;
342
343       /* if we get here, we can sync */
344       m_hasSync        = true;
345       m_outputRate     = m_sampleRate;
346       m_outputChannels = 2;
347       m_channelMap     = CAEChannelInfo(OutputMaps[0]);
348       m_channels       = AC3Channels[acmod] + lfeon;
349       m_syncFunc       = &CAEStreamInfo::SyncAC3;
350       m_dataType       = STREAM_TYPE_AC3;
351       m_packFunc       = &CAEPackIEC61937::PackAC3;
352       m_repeat         = 1;
353
354       CLog::Log(LOGINFO, "CAEStreamInfo::SyncAC3 - AC3 stream detected (%d channels, %dHz)", m_channels, m_sampleRate);
355       return skip;
356     }
357     else
358     {
359       /* Enhanced AC-3 */
360       uint8_t strmtyp = data[2] >> 6;
361       if (strmtyp == 3)
362         continue;
363
364       unsigned int framesize = (((data[2] & 0x7) << 8) | data[3]) + 1;
365       uint8_t      fscod     = (data[4] >> 6) & 0x3;
366       uint8_t      cod       = (data[4] >> 4) & 0x3;
367       uint8_t      blocks;
368
369       if (fscod == 0x3)
370       {
371         if (cod == 0x3)
372           continue;
373
374         blocks       = 6;
375         m_sampleRate = AC3FSCod[cod] >> 1;
376       }
377       else
378       {
379         blocks       = AC3BlkCod[cod  ];
380         m_sampleRate = AC3FSCod [fscod];
381       }
382
383       m_fsize        = framesize << 1;
384       m_repeat       = MAX_EAC3_BLOCKS / blocks;
385
386       if (m_sampleRate == 48000 || m_sampleRate == 96000 || m_sampleRate == 192000)
387         m_outputRate = 192000;
388       else
389         m_outputRate = 176400;
390
391       if (m_dataType == STREAM_TYPE_EAC3 && m_hasSync && skip == 0)
392         return 0;
393
394       /* if we get here, we can sync */
395       m_hasSync        = true;
396       m_outputChannels = 8;
397       m_channelMap     = CAEChannelInfo(OutputMaps[1]);
398       m_channels       = 8; /* FIXME: this should be read out of the stream */
399       m_syncFunc       = &CAEStreamInfo::SyncAC3;
400       m_dataType       = STREAM_TYPE_EAC3;
401       m_packFunc       = &CAEPackIEC61937::PackEAC3;
402
403       CLog::Log(LOGINFO, "CAEStreamInfo::SyncAC3 - E-AC3 stream detected (%d channels, %dHz)", m_channels, m_sampleRate);
404       return skip;
405     }
406   }
407
408   /* if we get here, the entire packet is invalid and we have lost sync */
409   CLog::Log(LOGINFO, "CAEStreamInfo::SyncAC3 - AC3 sync lost");
410   m_hasSync = false;
411   return skip;
412 }
413
414 unsigned int CAEStreamInfo::SyncDTS(uint8_t *data, unsigned int size)
415 {
416   if (size < 13)
417   {
418     if (m_needBytes < 13)
419       m_needBytes = 14;
420     return 0;
421   }
422
423   unsigned int skip = 0;
424   for (; size - skip > 13; ++skip, ++data)
425   {
426     unsigned int header = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
427     unsigned int hd_sync = 0;
428     bool match = true;
429     unsigned int dtsBlocks;
430     unsigned int amode;
431     unsigned int sfreq;
432     unsigned int lfe;
433     int bits;
434
435     switch (header)
436     {
437       /* 14bit BE */
438       case DTS_PREAMBLE_14BE:
439         if (data[4] != 0x07 || (data[5] & 0xf0) != 0xf0)
440         {
441           match = false;
442           break;
443         }
444         dtsBlocks = (((data[5] & 0x7) << 4) | ((data[6] & 0x3C) >> 2)) + 1;
445         m_fsize     = ((((data[6] & 0x3 << 8) | data[7]) << 4) | ((data[8] & 0x3C) >> 2)) + 1;
446         amode       = ((data[8] & 0x3) << 4) | ((data[9] & 0xF0) >> 4);
447         sfreq       = data[9] & 0xF;
448         lfe         = (data[12] & 0x18) >> 3;
449         m_dataIsLE  = false;
450         bits        = 14;
451         break;
452
453       /* 14bit LE */
454       case DTS_PREAMBLE_14LE:
455         if (data[5] != 0x07 || (data[4] & 0xf0) != 0xf0)
456         {
457           match = false;
458           break;
459         }
460         dtsBlocks = (((data[4] & 0x7) << 4) | ((data[7] & 0x3C) >> 2)) + 1;
461         m_fsize     = ((((data[7] & 0x3 << 8) | data[6]) << 4) | ((data[9] & 0x3C) >> 2)) + 1;
462         amode       = ((data[9] & 0x3) << 4) | ((data[8] & 0xF0) >> 4);
463         sfreq       = data[8] & 0xF;
464         lfe         = (data[13] & 0x18) >> 3;
465         m_dataIsLE  = true;
466         bits        = 14;
467         break;
468
469       /* 16bit BE */
470       case DTS_PREAMBLE_16BE:
471         dtsBlocks = (((data[4] & 0x1) << 7) | ((data[5] & 0xFC) >> 2)) + 1;
472         m_fsize     = (((((data[5] & 0x3) << 8) | data[6]) << 4) | ((data[7] & 0xF0) >> 4)) + 1;
473         amode       = ((data[7] & 0x0F) << 2) | ((data[8] & 0xC0) >> 6);
474         sfreq       = (data[8] & 0x3C) >> 2;
475         lfe         = (data[10] >> 1) & 0x3;
476         m_dataIsLE  = false;
477         bits        = 16;
478         break;
479
480       /* 16bit LE */
481       case DTS_PREAMBLE_16LE:
482         dtsBlocks = (((data[5] & 0x1) << 7) | ((data[4] & 0xFC) >> 2)) + 1;
483         m_fsize     = (((((data[4] & 0x3) << 8) | data[7]) << 4) | ((data[6] & 0xF0) >> 4)) + 1;
484         amode       = ((data[6] & 0x0F) << 2) | ((data[9] & 0xC0) >> 6);
485         sfreq       = (data[9] & 0x3C) >> 2;
486         lfe         = (data[11] >> 1) & 0x3;
487         m_dataIsLE  = true;
488         bits        = 16;
489         break;
490
491       default:
492         match = false;
493         break;
494     }
495
496     if (!match || sfreq == 0 || sfreq >= DTS_SFREQ_COUNT)
497       continue;
498
499     /* make sure the framesize is sane */
500     if (m_fsize < 96 || m_fsize > 16384)
501       continue;
502
503     bool invalid = false;
504     DataType dataType;
505     switch (dtsBlocks << 5)
506     {
507       case 512 : dataType = STREAM_TYPE_DTS_512 ; m_packFunc = &CAEPackIEC61937::PackDTS_512 ; break;
508       case 1024: dataType = STREAM_TYPE_DTS_1024; m_packFunc = &CAEPackIEC61937::PackDTS_1024; break;
509       case 2048: dataType = STREAM_TYPE_DTS_2048; m_packFunc = &CAEPackIEC61937::PackDTS_2048; break;
510       default:
511         invalid = true;
512         break;
513     }
514
515     if (invalid)
516       continue;
517
518     /* adjust the fsize for 14 bit streams */
519     if (bits == 14)
520       m_fsize = m_fsize / 14 * 16;
521
522     /* we need enough data to check for DTS-HD */
523     if (size - skip < m_fsize + 10)
524     {
525       /* we can assume DTS sync at this point */
526       m_syncFunc  = &CAEStreamInfo::SyncDTS;
527       m_needBytes = m_fsize + 10;
528       m_fsize     = 0;
529
530       return skip;
531     }
532
533     /* look for DTS-HD */
534     hd_sync = (data[m_fsize] << 24) | (data[m_fsize + 1] << 16) | (data[m_fsize + 2] << 8) | data[m_fsize + 3];
535     if (hd_sync == DTS_PREAMBLE_HD)
536     {
537       int hd_size;
538       bool blownup = (data[m_fsize + 5] & 0x20) != 0;
539       if (blownup)
540         hd_size = (((data[m_fsize + 6] & 0x01) << 19) | (data[m_fsize + 7] << 11) | (data[m_fsize + 8] << 3) | ((data[m_fsize + 9] & 0xe0) >> 5)) + 1;
541       else
542         hd_size = (((data[m_fsize + 6] & 0x1f) << 11) | (data[m_fsize + 7] << 3) | ((data[m_fsize + 8] & 0xe0) >> 5)) + 1;
543
544       /* set the type according to core or not */
545       if (m_coreOnly)
546         dataType = STREAM_TYPE_DTSHD_CORE;
547       else
548         dataType = STREAM_TYPE_DTSHD;
549
550       m_coreSize  = m_fsize;
551       m_fsize    += hd_size;
552     }
553
554     unsigned int sampleRate = DTSSampleRates[sfreq];
555     if (!m_hasSync || skip || dataType != m_dataType || sampleRate != m_sampleRate || dtsBlocks != m_dtsBlocks)
556     {
557       m_hasSync        = true;
558       m_dataType       = dataType;
559       m_sampleRate     = sampleRate;
560       m_dtsBlocks      = dtsBlocks;
561       m_channels       = DTSChannels[amode] + (lfe ? 1 : 0);
562       m_syncFunc       = &CAEStreamInfo::SyncDTS;
563       m_repeat         = 1;
564
565       if (dataType == STREAM_TYPE_DTSHD)
566       {
567         m_outputRate     = 192000;
568         m_outputChannels = 8;
569         m_channelMap     = CAEChannelInfo(OutputMaps[1]);
570         m_channels      += 2; /* FIXME: this needs to be read out, not sure how to do that yet */
571       }
572       else
573       {
574         m_outputRate     = m_sampleRate;
575         m_outputChannels = 2;
576         m_channelMap     = CAEChannelInfo(OutputMaps[0]);
577       }
578
579       std::string type;
580       switch (dataType)
581       {
582         case STREAM_TYPE_DTSHD     : type = "dtsHD"; break;
583         case STREAM_TYPE_DTSHD_CORE: type = "dtsHD (core)"; break;
584         default                    : type = "dts"; break;
585       }
586
587       /* calculate the period size for dtsHD */
588       m_dtsPeriod = (m_outputRate * (m_outputChannels >> 1)) * (m_dtsBlocks << 5) / m_sampleRate;
589
590       CLog::Log(LOGINFO, "CAEStreamInfo::SyncDTS - %s stream detected (%d channels, %dHz, %dbit %s, period: %u)",
591                 type.c_str(), m_channels, m_sampleRate,
592                 bits, m_dataIsLE ? "LE" : "BE",
593                 m_dtsPeriod);
594     }
595
596     return skip;
597   }
598
599   /* lost sync */
600   CLog::Log(LOGINFO, "CAEStreamInfo::SyncDTS - DTS sync lost");
601   m_hasSync = false;
602   return skip;
603 }
604
605 inline unsigned int CAEStreamInfo::GetTrueHDChannels(const uint16_t chanmap)
606 {
607   int channels = 0;
608   for (int i = 0; i < 13; ++i)
609     channels += THDChanMap[i] * ((chanmap >> i) & 1);
610   return channels;
611 }
612
613 unsigned int CAEStreamInfo::SyncTrueHD(uint8_t *data, unsigned int size)
614 {
615   unsigned int left = size;
616   unsigned int skip = 0;
617
618   /* if MLP */
619   for (; left; ++skip, ++data, --left)
620   {
621     /* if we dont have sync and there is less the 8 bytes, then break out */
622     if (!m_hasSync && left < 8)
623       return size;
624
625     /* if its a major audio unit */
626     uint16_t length   = ((data[0] & 0x0F) << 8 | data[1]) << 1;
627     uint32_t syncword = ((((data[4] << 8 | data[5]) << 8) | data[6]) << 8) | data[7];
628     if (syncword == 0xf8726fba)
629     {
630       /* we need 32 bytes to sync on a master audio unit */
631       if (left < 32)
632         return skip;
633
634       /* get the rate and ensure its valid */
635       int rate = (data[8] & 0xf0) >> 4;
636       if (rate == 0xF)
637         continue;
638
639       /* verify the crc of the audio unit */
640       uint16_t crc = m_dllAvUtil.av_crc(m_crcTrueHD, 0, data + 4, 24);
641       crc ^= (data[29] << 8) | data[28];
642       if (((data[31] << 8) | data[30]) != crc)
643         continue;
644
645       /* get the sample rate and substreams, we have a valid master audio unit */
646       m_sampleRate = (rate & 0x8 ? 44100 : 48000) << (rate & 0x7);
647       m_substreams = (data[20] & 0xF0) >> 4;
648
649       /* get the number of encoded channels */
650       uint16_t channel_map = ((data[10] & 0x1F) << 8) | data[11];
651       if (!channel_map)
652         channel_map = (data[9] << 1) | (data[10] >> 7);
653       m_channels = CAEStreamInfo::GetTrueHDChannels(channel_map);
654
655       if (m_sampleRate == 48000 || m_sampleRate == 96000 || m_sampleRate == 192000)
656         m_outputRate = 192000;
657       else
658         m_outputRate = 176400;
659
660       if (!m_hasSync)
661         CLog::Log(LOGINFO, "CAEStreamInfo::SyncTrueHD - TrueHD stream detected (%d channels, %dHz)", m_channels, m_sampleRate);
662
663       m_hasSync        = true;
664       m_fsize          = length;
665       m_dataType       = STREAM_TYPE_TRUEHD;
666       m_outputChannels = 8;
667       m_channelMap     = CAEChannelInfo(OutputMaps[1]);
668       m_syncFunc       = &CAEStreamInfo::SyncTrueHD;
669       m_packFunc       = &CAEPackIEC61937::PackTrueHD;
670       m_repeat         = 1;
671       return skip;
672     }
673     else
674     {
675       /* we cant sink to a subframe until we have the information from a master audio unit */
676       if (!m_hasSync)
677         continue;
678
679       /* if there is not enough data left to verify the packet, just return the skip amount */
680       if (left < (unsigned int)m_substreams * 4)
681         return skip;
682
683       /* verify the parity */
684       int     p     = 0;
685       uint8_t check = 0;
686       for (int i = -1; i < m_substreams; ++i)
687       {
688         check ^= data[p++];
689         check ^= data[p++];
690         if (i == -1 || data[p - 2] & 0x80)
691         {
692           check ^= data[p++];
693           check ^= data[p++];
694         }
695       }
696
697       /* if the parity nibble does not match */
698       if ((((check >> 4) ^ check) & 0xF) != 0xF)
699       {
700         /* lost sync */
701         m_hasSync  = false;
702         CLog::Log(LOGINFO, "CAEStreamInfo::SyncTrueHD - Sync Lost");
703         continue;
704       }
705       else
706       {
707         m_fsize = length;
708         return skip;
709       }
710     }
711   }
712
713   /* lost sync */
714   m_hasSync  = false;
715   return skip;
716 }
717