1 /**
2 
3         \file ADM_dcainfo
4         \brief extract info from DTS/DCA streams
5         Author: mean <fixounet@free.fr>, (C) 2004
6         Code very derived from libdca
7 
8 */
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 #include "ADM_default.h"
18 #include "ADM_dcainfo.h"
19 #include "ADM_getbits.h"
20 #undef printf
21 /*
22         Borrowed from libdca
23 */
24 static const int dts_sample_rates[] =
25 {
26     0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
27     12000, 24000, 48000, 96000, 192000
28 };
29 
30 static const int dts_bit_rates[] =
31 {
32     32000, 56000, 64000, 96000, 112000, 128000,
33     192000, 224000, 256000, 320000, 384000,
34     448000, 512000, 576000, 640000, 768000,
35     896000, 1024000, 1152000, 1280000, 1344000,
36     1408000, 1411200, 1472000, 1536000, 1920000,
37     2048000, 3072000, 3840000, 1/*open*/, 2/*variable*/, 3/*lossless*/
38 };
39 
40 static const uint8_t dts_channels[] =
41 {
42     1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8
43 };
44 
45 /**
46     \fn ADM_DCAGetInfo
47     @param syncoff: # of dropped bytes from the begining
48 */
ADM_DCAGetInfo(uint8_t * buf,uint32_t len,ADM_DCA_INFO * info,uint32_t * syncoff)49 bool ADM_DCAGetInfo(uint8_t *buf, uint32_t len,ADM_DCA_INFO *info,uint32_t *syncoff)
50 //int  ADM_DCAGetInfo(uint8_t *buf, uint32_t len, uint32_t *fq, uint32_t *br, uint32_t *chan,uint32_t *syncoff,uint32_t *flagso,uint32_t *nbSample)
51 {
52 uint8_t *end=buf+len-4-DTS_HEADER_SIZE;
53 uint8_t *cur=buf-1;
54 uint32_t len1,len2,flags,framesize=0,index,nbBlocks;
55              // Assume 16 bits big endian
56             // Search for 7F FE 80 01 as sync start
57             *syncoff=0;
58             while(cur<end)
59             {
60                 cur++;
61                 if(*cur!=0x7F) continue;
62                 if(cur[1]!=0xfe) continue;
63                 if(cur[2]!=0x80) continue;
64                 if(cur[3]!=0x01) continue;
65                 // ok we got a starcode
66                 // State :      32 bits, already got them
67                 // Frame type   1
68                 // Sample Deficit 5
69                 // CRC present  1
70                 // Frame length  7
71                 // Frame Size 14
72                 // **** Inefficient ! ****
73                 getBits bits((int)(end-cur),cur);
74                 bits.skip(32);
75                 bits.skip(1);
76                 bits.skip(5);
77                 bits.skip(1);
78                 //Nb Samples
79                 nbBlocks=1+bits.get(7);
80                 // Frame size in bit
81                 len2=bits.get(14);
82                 framesize=len2+1;
83                 //
84                 //
85                 //
86                 flags=bits.get(6);
87                 info->flags=flags;
88                 index=bits.get(4);
89                 info->frequency=dts_sample_rates[index];
90                 index=bits.get(5);
91                 info->bitrate=dts_bit_rates[index];
92 #if 0
93                 printf("[dts]Flags  :%u\n",flags);
94                 printf("[dts]Fq  :%u\n",*fq);
95                 printf("[dts]br  :%u\n",*br);
96                 printf("[dts]len1  :%u\n",len1);
97                 printf("[dts]len2  :%u\n",len2);
98 #endif
99                 *syncoff=cur-buf;
100                 if(*syncoff) ADM_warning("[dts] Dropped %u bytes\n",*syncoff);
101                 bits.get(10);
102                 int lfe=bits.get(2);
103                 int c;
104                 c=dts_channels[flags & 0xf];
105                 if(c==5 && lfe) c++; // LFE
106                 info->channels=c;
107                 info->samples=nbBlocks*32;
108                 info->frameSizeInBytes=framesize;
109                 return true;
110 
111 
112             }
113             ADM_warning("[DTS] Cannot find sync %x %x %x %x\n",buf[0],buf[1],buf[2],buf[3]);
114 	      return false;
115 }
116 
117