blob: 31bca7c6d8595981d48a64b6fe8e16b4a5c494a8
1 | /* ***** BEGIN LICENSE BLOCK ***** |
2 | * Source last modified: $Id: ga_config.c,v 1.1.1.1.2.1 2005/05/04 18:21:58 hubbe Exp $ |
3 | * |
4 | * REALNETWORKS CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM |
5 | * Portions Copyright (c) 1995-2005 RealNetworks, Inc. |
6 | * All Rights Reserved. |
7 | * |
8 | * The contents of this file, and the files included with this file, |
9 | * are subject to the current version of the Real Format Source Code |
10 | * Porting and Optimization License, available at |
11 | * https://helixcommunity.org/2005/license/realformatsource (unless |
12 | * RealNetworks otherwise expressly agrees in writing that you are |
13 | * subject to a different license). You may also obtain the license |
14 | * terms directly from RealNetworks. You may not use this file except |
15 | * in compliance with the Real Format Source Code Porting and |
16 | * Optimization License. There are no redistribution rights for the |
17 | * source code of this file. Please see the Real Format Source Code |
18 | * Porting and Optimization License for the rights, obligations and |
19 | * limitations governing use of the contents of the file. |
20 | * |
21 | * RealNetworks is the developer of the Original Code and owns the |
22 | * copyrights in the portions it created. |
23 | * |
24 | * This file, and the files included with this file, is distributed and |
25 | * made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, |
26 | * EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL |
27 | * SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
28 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT |
29 | * OR NON-INFRINGEMENT. |
30 | * |
31 | * Technology Compatibility Kit Test Suite(s) Location: |
32 | * https://rarvcode-tck.helixcommunity.org |
33 | * |
34 | * Contributor(s): |
35 | * |
36 | * ***** END LICENSE BLOCK ***** */ |
37 | |
38 | /* parse an MPEG-4 general audio specific config structure from a bitstream */ |
39 | |
40 | #include "ga_config.h" |
41 | #include "aac_bitstream.h" |
42 | |
43 | const UINT32 aSampleRate[13] = { |
44 | 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, |
45 | 11025, 8000, 7350 |
46 | }; |
47 | |
48 | const UINT32 channelMapping[][4] = { |
49 | {0, 0, 0, 0}, |
50 | {1, 0, 0, 0}, /* center */ |
51 | {2, 0, 0, 0}, /* left, right */ |
52 | {3, 0, 0, 0}, /* center, left, right */ |
53 | {3, 0, 1, 0}, /* center, left, right, rear surround */ |
54 | {3, 0, 2, 0}, /* center, left, right, left surround, right surround */ |
55 | {3, 0, 2, 1}, /* center, left, right, left surround, right surround, lfe */ |
56 | {5, 0, 2, 1}, /* center, left, right, left outside, right outside, left surround, right surround, lfe */ |
57 | }; |
58 | |
59 | UINT32 ga_config_get_data(struct BITSTREAM *bs, ga_config_data *data) |
60 | { |
61 | UINT32 i; |
62 | UINT32 index = 0; |
63 | UINT32 flag = 0; |
64 | UINT32 skip = 0; |
65 | UINT32 channelConfig = 0; |
66 | |
67 | /* audio object type */ |
68 | data->audioObjectType = readBits(bs, 5); |
69 | |
70 | /* sampling frequency */ |
71 | index = readBits(bs, 4); |
72 | if (index == 0xF) { |
73 | data->samplingFrequency = readBits(bs, 24); |
74 | } else { |
75 | data->samplingFrequency = aSampleRate[index]; |
76 | } |
77 | |
78 | /* channel configuration */ |
79 | channelConfig = readBits(bs, 4); |
80 | |
81 | /* sbr parameters */ |
82 | if (data->audioObjectType == AACSBR) { |
83 | data->bSBR = TRUE; |
84 | index = readBits(bs, 4); |
85 | if (index == 0xF) { |
86 | data->extensionSamplingFrequency = readBits(bs, 24); |
87 | } else { |
88 | data->extensionSamplingFrequency = readBits(bs, 24); |
89 | } |
90 | |
91 | data->audioObjectType = readBits(bs, 5); |
92 | } else { |
93 | data->extensionSamplingFrequency = data->samplingFrequency; |
94 | data->bSBR = FALSE; |
95 | } |
96 | |
97 | /* make sure format is supported */ |
98 | if (data->audioObjectType == AACMAIN || |
99 | data->audioObjectType == AACLC || |
100 | data->audioObjectType == AACLTP) { |
101 | flag = readBits(bs, 1); |
102 | data->frameLength = flag ? 960 : 1024; |
103 | |
104 | flag = readBits(bs, 1); |
105 | if (flag) { |
106 | data->coreCoderDelay = readBits(bs, 14); |
107 | } |
108 | |
109 | flag = readBits(bs, 1); /* extension flag - not defined */ |
110 | |
111 | if (channelConfig == 0) { |
112 | skip = readBits(bs, 4); /* ignore element instance tag */ |
113 | skip = readBits(bs, 2); /* ignore object type */ |
114 | skip = readBits(bs, 4); /* ignore sampling frequency index */ |
115 | |
116 | data->numFrontElements = readBits(bs, 4); |
117 | data->numSideElements = readBits(bs, 4); |
118 | data->numBackElements = readBits(bs, 4); |
119 | data->numLfeElements = readBits(bs, 2); |
120 | data->numAssocElements = readBits(bs, 3); |
121 | data->numValidCCElements = readBits(bs, 4); |
122 | |
123 | if (readBits(bs, 1)) { /* mono mixdown present */ |
124 | skip = readBits(bs, 4); /* ignore mixdown element */ |
125 | } |
126 | |
127 | if (readBits(bs, 1)) { /* stereo mixdown present */ |
128 | skip = readBits(bs, 4); /* ignore mixdown element */ |
129 | } |
130 | |
131 | if (readBits(bs, 1)) { /* matrix mixdown present */ |
132 | skip = readBits(bs, 2); /* ignore mixdown index */ |
133 | skip = readBits(bs, 1); /* ignore surround enable */ |
134 | } |
135 | |
136 | for (i = 0; i < data->numFrontElements; i++) { |
137 | data->numFrontChannels += (1 + readBits(bs, 1)); |
138 | skip = readBits(bs, 4); /* ignore tag select */ |
139 | } |
140 | for (i = 0; i < data->numSideElements; i++) { |
141 | data->numSideChannels += (1 + readBits(bs, 1)); |
142 | skip = readBits(bs, 4); /* ignore tag select */ |
143 | } |
144 | for (i = 0; i < data->numBackElements; i++) { |
145 | data->numBackChannels += (1 + readBits(bs, 1)); |
146 | skip = readBits(bs, 4); /* ignore tag select */ |
147 | } |
148 | for (i = 0; i < data->numLfeElements; i++) { |
149 | skip = readBits(bs, 4); /* ignore tag select */ |
150 | } |
151 | for (i = 0; i < data->numAssocElements; i++) { |
152 | skip = readBits(bs, 4); /* ignore tag select */ |
153 | } |
154 | for (i = 0; i < data->numValidCCElements; i++) { |
155 | skip = readBits(bs, 1); /* ignore 'is_ind_sw' */ |
156 | skip = readBits(bs, 4); /* ignore tag select */ |
157 | } |
158 | |
159 | byteAlign(bs); |
160 | |
161 | /* ignore comment field data */ |
162 | index = readBits(bs, 8); |
163 | for (i = 0; i < index; i++) { |
164 | skip = readBits(bs, 8); |
165 | } |
166 | } else { |
167 | if (channelConfig >= 8) { |
168 | return HXR_FAIL; |
169 | } |
170 | |
171 | data->numFrontChannels = channelMapping[channelConfig][0]; |
172 | data->numSideChannels = channelMapping[channelConfig][1]; |
173 | data->numBackChannels = channelMapping[channelConfig][2]; |
174 | data->numLfeElements = channelMapping[channelConfig][3]; |
175 | |
176 | data->numFrontElements = (data->numFrontChannels + 1) >> 1; |
177 | data->numSideElements = (data->numSideChannels + 1) >> 1; |
178 | data->numBackElements = (data->numBackChannels + 1) >> 1; |
179 | } |
180 | |
181 | data->numChannels = data->numFrontChannels + |
182 | data->numSideChannels + |
183 | data->numBackChannels + |
184 | data->numLfeElements; |
185 | |
186 | } else { /* format not supported */ |
187 | return HXR_FAIL; |
188 | } |
189 | |
190 | /* check for SBR info if there is enough data left in the bitstream */ |
191 | if (!data->bSBR && bitsLeftInBitstream(bs) >= 16) { |
192 | if (readBits(bs, 11) == 0x2b7) { |
193 | if (readBits(bs, 5) == 5) { |
194 | data->bSBR = readBits(bs, 1); |
195 | |
196 | if (data->bSBR) { |
197 | index = readBits(bs, 4); |
198 | if (index == 0xF) { |
199 | data->extensionSamplingFrequency = readBits(bs, 24); |
200 | } else { |
201 | data->extensionSamplingFrequency = aSampleRate[index]; |
202 | } |
203 | } |
204 | } |
205 | } |
206 | } |
207 | |
208 | return HXR_OK; |
209 | } |
210 |