1 //
2 // C++ Implementation: ADM_a52info
3 //
4 // Description:
5 //
6 //
7 // Author: mean <fixounet@free.fr>, (C) 2004
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12
13
14 #include "ADM_default.h"
15
16 #include "ADM_a52info.h"
17
18 #define A52_CHANNEL 0
19 #define A52_MONO 1
20 #define A52_STEREO 2
21 #define A52_3F 3
22 #define A52_2F1R 4
23 #define A52_3F1R 5
24 #define A52_2F2R 6
25 #define A52_3F2R 7
26 #define A52_CHANNEL1 8
27 #define A52_CHANNEL2 9
28 #define A52_DOLBY 10
29 #define A52_CHANNEL_MASK 15
30
31 #define A52_LFE 16
32 #define A52_ADJUST_LEVEL 32
33
34 static uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
35
36 static int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
37 128, 160, 192, 224, 256, 320, 384, 448,
38 512, 576, 640};
39 static uint8_t lfeon[8] = {0x10, 0x10, 0x04, 0x04, 0x04, 0x01, 0x04, 0x01};
40 /**
41 \fn ADM_a52_syncinfo
42 \brief Return packed size on success, 0 on failure
43 Need at least 6 bytes incoming
44 Borrowed from a52dec
45 */
ADM_a52_syncinfo(const uint8_t * buf,int * flags,int * sample_rate,int * bit_rate)46 int ADM_a52_syncinfo (const uint8_t * buf, int * flags, int * sample_rate, int * bit_rate)
47 {
48 int frmsizecod;
49 int bitrate;
50 int half;
51 int acmod;
52
53 if ((buf[0] != 0x0b) || (buf[1] != 0x77)) /* syncword */
54 return 0;
55
56 if (buf[5] >= 0x60) /* bsid >= 12 */
57 return 0;
58 half = halfrate[buf[5] >> 3];
59
60 /* acmod, dsurmod and lfeon */
61 acmod = buf[6] >> 5;
62 *flags = ((((buf[6] & 0xf8) == 0x50) ? A52_DOLBY : acmod) |
63 ((buf[6] & lfeon[acmod]) ? A52_LFE : 0));
64
65 frmsizecod = buf[4] & 63;
66 if (frmsizecod >= 38)
67 return 0;
68 bitrate = rate [frmsizecod >> 1];
69 *bit_rate = (bitrate * 1000) >> half;
70
71 switch (buf[4] & 0xc0) {
72 case 0:
73 *sample_rate = 48000 >> half;
74 return 4 * bitrate;
75 case 0x40:
76 *sample_rate = 44100 >> half;
77 return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
78 case 0x80:
79 *sample_rate = 32000 >> half;
80 return 6 * bitrate;
81 default:
82 return 0;
83 }
84 }
85 /**
86 \fn ADM_AC3GetInfo
87 \brief Extract infos from AC3 stream (used when muxing with external AC3)
88 */
ADM_AC3GetInfo(const uint8_t * buf,uint32_t len,uint32_t * fq,uint32_t * br,uint32_t * chan,uint32_t * syncoff)89 uint8_t ADM_AC3GetInfo(const uint8_t *buf, uint32_t len, uint32_t *fq, uint32_t *br, uint32_t *chan,uint32_t *syncoff)
90 {
91 uint32_t l;
92 int ibr,ifq,flags;
93 uint32_t of=0;
94
95 *syncoff=of=0;
96 printf("\n Syncing on %d \n",len);
97 // Search for startcode
98 // 0x0b 0x77
99 while(1)
100 {
101 if(len<7)
102 {
103 printf("Not enough info to find a52 syncword\n");
104 return 0;
105 }
106 if( *buf!=0x0b || *(buf+1)!=0x77)
107 {
108 len--;
109 buf++;
110 of++;
111 continue;
112 }
113 // Try to get syncinfo
114 l=ADM_a52_syncinfo (buf,&flags, &ifq, &ibr);
115 if(!l)
116 {
117 len--;
118 buf++;
119 of++;
120 printf("Sync failed..continuing\n");
121 continue;
122 }
123 printf("Sync found at offset %" PRIu32"\n",of);
124 *syncoff=of;
125 *fq=(uint32_t)ifq;
126 *br=(uint32_t)ibr>>3;
127 switch (flags & A52_CHANNEL_MASK) {
128 case A52_CHANNEL:
129 case A52_MONO:
130 *chan = 1;
131 break;
132 case A52_STEREO:
133 case A52_DOLBY:
134 *chan = 2;
135 break;
136 case A52_3F:
137 case A52_2F1R:
138 *chan = 3;
139 break;
140 case A52_3F1R:
141 case A52_2F2R:
142 *chan = 4;
143 break;
144 case A52_3F2R:
145 *chan = 5;
146 break;
147 default:
148 ADM_assert(0);
149 }
150 if (flags & A52_LFE)
151 (*chan)++;
152 return 1;
153 }
154 return 0;
155 }
156