1 /*****************************************************************
2 |
3 |    AP4 - AAC ADTS Parser
4 |
5 |    Copyright 2002-2008 Axiomatic Systems, LLC
6 |
7 |
8 |    This file is part of Bento4/AP4 (MP4 Atom Processing Library).
9 |
10 |    Unless you have obtained Bento4 under a difference license,
11 |    this version of Bento4 is Bento4|GPL.
12 |    Bento4|GPL is free software; you can redistribute it and/or modify
13 |    it under the terms of the GNU General Public License as published by
14 |    the Free Software Foundation; either version 2, or (at your option)
15 |    any later version.
16 |
17 |    Bento4|GPL is distributed in the hope that it will be useful,
18 |    but WITHOUT ANY WARRANTY; without even the implied warranty of
19 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 |    GNU General Public License for more details.
21 |
22 |    You should have received a copy of the GNU General Public License
23 |    along with Bento4|GPL; see the file COPYING.  If not, write to the
24 |    Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 |    02111-1307, USA.
26 |
27 ****************************************************************/
28 
29 /*----------------------------------------------------------------------
30 |   includes
31 +---------------------------------------------------------------------*/
32 #include "Ap4BitStream.h"
33 #include "Ap4AdtsParser.h"
34 
35 /*----------------------------------------------------------------------
36 |   constants
37 +---------------------------------------------------------------------*/
38 #define AP4_ADTS_HEADER_SIZE 7
39 
40 #define AP4_ADTS_SYNC_MASK     0xFFF6 /* 12 sync bits plus 2 layer bits */
41 #define AP4_ADTS_SYNC_PATTERN  0xFFF0 /* 12 sync bits=1 layer=0         */
42 
43 const AP4_UI32
44 AP4_AdtsSamplingFrequencyTable[16] =
45 {
46     96000,
47     88200,
48     64000,
49     48000,
50     44100,
51     32000,
52     24000,
53     22050,
54     16000,
55     12000,
56     11025,
57     8000,
58     7350,
59     0,      /* Reserved */
60     0,      /* Reserved */
61     0       /* Escape code */
62 };
63 
64 /*----------------------------------------------------------------------+
65 |    AP4_AdtsHeader::AP4_AdtsHeader
66 +----------------------------------------------------------------------*/
AP4_AdtsHeader(const AP4_UI08 * bytes)67 AP4_AdtsHeader::AP4_AdtsHeader(const AP4_UI08* bytes)
68 {
69     // fixed part
70     m_Id                     = ( bytes[1] & 0x08) >> 3;
71     m_ProtectionAbsent       =   bytes[1] & 0x01;
72     m_ProfileObjectType      = ( bytes[2] & 0xC0) >> 6;
73     m_SamplingFrequencyIndex = ( bytes[2] & 0x3C) >> 2;
74     m_ChannelConfiguration   = ((bytes[2] & 0x01) << 2) |
75                                ((bytes[3] & 0xC0) >> 6);
76     // variable part
77     m_FrameLength = ((unsigned int)(bytes[3] & 0x03) << 11) |
78                     ((unsigned int)(bytes[4]       ) <<  3) |
79                     ((unsigned int)(bytes[5] & 0xE0) >>  5);
80     m_RawDataBlocks =               bytes[6] & 0x03;
81 }
82 
83 /*----------------------------------------------------------------------+
84 |    AP4_AdtsHeader::MatchFixed
85 |
86 |    Check that two fixed headers are the same
87 |
88 +----------------------------------------------------------------------*/
89 bool
MatchFixed(unsigned char * a,unsigned char * b)90 AP4_AdtsHeader::MatchFixed(unsigned char* a, unsigned char* b)
91 {
92     if (a[0]         ==  b[0] &&
93         a[1]         ==  b[1] &&
94         a[2]         ==  b[2] &&
95        (a[3] & 0xF0) == (b[3] & 0xF0)) {
96         return true;
97     } else {
98         return false;
99     }
100 }
101 
102 /*----------------------------------------------------------------------+
103 |    AP4_AdtsHeader::Check
104 +----------------------------------------------------------------------*/
105 AP4_Result
Check()106 AP4_AdtsHeader::Check()
107 {
108     // check that the sampling frequency index is valid
109     if (m_SamplingFrequencyIndex >= 0xD) {
110         return AP4_FAILURE;
111     }
112 
113     /* MPEG2 does not use all profiles */
114     if (m_Id == 1 && m_ProfileObjectType == 3) {
115         return AP4_FAILURE;
116     }
117 
118     return AP4_SUCCESS;
119 }
120 
121 /*----------------------------------------------------------------------+
122 |    AP4_AdtsParser::AP4_AdtsParser
123 +----------------------------------------------------------------------*/
AP4_AdtsParser()124 AP4_AdtsParser::AP4_AdtsParser() :
125     m_FrameCount(0)
126 {
127 }
128 
129 /*----------------------------------------------------------------------+
130 |    AP4_AdtsParser::~AP4_AdtsParser
131 +----------------------------------------------------------------------*/
~AP4_AdtsParser()132 AP4_AdtsParser::~AP4_AdtsParser()
133 {
134 }
135 
136 /*----------------------------------------------------------------------+
137 |    AP4_AdtsParser::Reset
138 +----------------------------------------------------------------------*/
139 AP4_Result
Reset()140 AP4_AdtsParser::Reset()
141 {
142     m_FrameCount = 0;
143 
144     return AP4_SUCCESS;
145 }
146 
147 /*----------------------------------------------------------------------+
148 |    AP4_AdtsParser::Feed
149 +----------------------------------------------------------------------*/
150 AP4_Result
Feed(const AP4_UI08 * buffer,AP4_Size * buffer_size,AP4_Flags flags)151 AP4_AdtsParser::Feed(const AP4_UI08* buffer,
152                      AP4_Size*       buffer_size,
153                      AP4_Flags       flags)
154 {
155     AP4_Size free_space;
156 
157     /* update flags */
158     m_Bits.m_Flags = flags;
159 
160     /* possible shortcut */
161     if (buffer == NULL ||
162         buffer_size == NULL ||
163         *buffer_size == 0) {
164         return AP4_SUCCESS;
165     }
166 
167     /* see how much data we can write */
168     free_space = m_Bits.GetBytesFree();
169     if (*buffer_size > free_space) *buffer_size = free_space;
170     if (*buffer_size == 0) return AP4_SUCCESS;
171 
172     /* write the data */
173     return m_Bits.WriteBytes(buffer, *buffer_size);
174 }
175 
176 /*----------------------------------------------------------------------+
177 |    AP4_AdtsParser::FindHeader
178 +----------------------------------------------------------------------*/
179 AP4_Result
FindHeader(AP4_UI08 * header)180 AP4_AdtsParser::FindHeader(AP4_UI08* header)
181 {
182     AP4_Size available = m_Bits.GetBytesAvailable();
183 
184     /* look for the sync pattern */
185     while (available-- >= AP4_ADTS_HEADER_SIZE) {
186         m_Bits.PeekBytes(header, 2);
187 
188         if ((((header[0] << 8) | header[1]) & AP4_ADTS_SYNC_MASK) == AP4_ADTS_SYNC_PATTERN) {
189             /* found a sync pattern, read the entire the header */
190             m_Bits.PeekBytes(header, AP4_ADTS_HEADER_SIZE);
191 
192            return AP4_SUCCESS;
193         } else {
194             m_Bits.ReadByte(); // skip
195         }
196     }
197 
198     return AP4_ERROR_NOT_ENOUGH_DATA;
199 }
200 
201 /*----------------------------------------------------------------------+
202 |    AP4_AdtsParser::FindFrame
203 +----------------------------------------------------------------------*/
204 AP4_Result
FindFrame(AP4_AacFrame & frame)205 AP4_AdtsParser::FindFrame(AP4_AacFrame& frame)
206 {
207     unsigned int   available;
208     unsigned char  raw_header[AP4_ADTS_HEADER_SIZE];
209     AP4_Result     result;
210 
211     /* align to the start of the next byte */
212     m_Bits.ByteAlign();
213 
214     /* find a frame header */
215     result = FindHeader(raw_header);
216     if (AP4_FAILED(result)) return result;
217 
218     /* parse the header */
219     AP4_AdtsHeader adts_header(raw_header);
220 
221     /* check the header */
222     result = adts_header.Check();
223     if (AP4_FAILED(result)) goto fail;
224 
225     /* check if we have enough data to peek at the next header */
226     available = m_Bits.GetBytesAvailable();
227     if (available >= adts_header.m_FrameLength+AP4_ADTS_HEADER_SIZE) {
228         // enough to peek at the header of the next frame
229         unsigned char peek_raw_header[AP4_ADTS_HEADER_SIZE];
230 
231         m_Bits.SkipBytes(adts_header.m_FrameLength);
232         m_Bits.PeekBytes(peek_raw_header, AP4_ADTS_HEADER_SIZE);
233         m_Bits.SkipBytes(-((int)adts_header.m_FrameLength));
234 
235         /* check the header */
236         AP4_AdtsHeader peek_adts_header(peek_raw_header);
237         result = peek_adts_header.Check();
238         if (AP4_FAILED(result)) goto fail;
239 
240         /* check that the fixed part of this header is the same as the */
241         /* fixed part of the previous header                           */
242         if (!AP4_AdtsHeader::MatchFixed(peek_raw_header, raw_header)) {
243             goto fail;
244         }
245     } else if (available < adts_header.m_FrameLength || (m_Bits.m_Flags & AP4_BITSTREAM_FLAG_EOS) == 0) {
246         // not enough for a frame, or not at the end (in which case we'll want to peek at the next header)
247         return AP4_ERROR_NOT_ENOUGH_DATA;
248     }
249 
250     m_Bits.SkipBytes(AP4_ADTS_HEADER_SIZE);
251 
252     /* fill in the frame info */
253     frame.m_Info.m_Standard = (adts_header.m_Id == 1 ?
254                             AP4_AAC_STANDARD_MPEG2 :
255                             AP4_AAC_STANDARD_MPEG4);
256     switch (adts_header.m_ProfileObjectType) {
257         case 0:
258             frame.m_Info.m_Profile = AP4_AAC_PROFILE_MAIN;
259             break;
260 
261         case 1:
262             frame.m_Info.m_Profile = AP4_AAC_PROFILE_LC;
263             break;
264 
265         case 2:
266             frame.m_Info.m_Profile = AP4_AAC_PROFILE_SSR;
267             break;
268 
269         case 3:
270             frame.m_Info.m_Profile = AP4_AAC_PROFILE_LTP;
271     }
272     frame.m_Info.m_FrameLength = adts_header.m_FrameLength-AP4_ADTS_HEADER_SIZE;
273     frame.m_Info.m_ChannelConfiguration = adts_header.m_ChannelConfiguration;
274     frame.m_Info.m_SamplingFrequencyIndex = adts_header.m_SamplingFrequencyIndex;
275     frame.m_Info.m_SamplingFrequency = AP4_AdtsSamplingFrequencyTable[adts_header.m_SamplingFrequencyIndex];
276 
277     /* skip crc if present */
278     if (adts_header.m_ProtectionAbsent == 0) {
279         m_Bits.SkipBits(16);
280     }
281 
282     /* set the frame source */
283     frame.m_Source = &m_Bits;
284 
285     return AP4_SUCCESS;
286 
287 fail:
288     /* skip the header and return (only skip the first byte in  */
289     /* case this was a false header that hides one just after)  */
290     //m_Bits.SkipBytes(-(AP4_ADTS_HEADER_SIZE-1));
291     return AP4_ERROR_CORRUPTED_BITSTREAM;
292 }
293 
294 /*----------------------------------------------------------------------+
295 |    AP4_AdtsParser::GetBytesFree
296 +----------------------------------------------------------------------*/
297 AP4_Size
GetBytesFree()298 AP4_AdtsParser::GetBytesFree()
299 {
300 	return (m_Bits.GetBytesFree());
301 }
302 
303 
304 
305 /*----------------------------------------------------------------------+
306 |    AP4_AdtsParser::GetBytesAvailable
307 +----------------------------------------------------------------------*/
308 AP4_Size
GetBytesAvailable()309 AP4_AdtsParser::GetBytesAvailable()
310 {
311 	return (m_Bits.GetBytesAvailable());
312 }
313 
314 
315 
316