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