1 /***************************************************************************
2 \file ADM_aacLatm.cpp
3 \brief Extract aac packet from LOAS/LATM stream
4 Derived from vlc code, seel ADM_aacLatm.h for vlc (c)
5 *
6 * http://www.nhzjj.com/asp/admin/editor/newsfile/2010318163752818.pdf
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
18 #include <math.h>
19 #include "ADM_default.h"
20 extern "C" {
21 #include "libavcodec/avcodec.h"
22 }
23 #include "ADM_aacLatm.h"
24
25 #define COOKIE ((AVBitStreamFilterContext *)cookie)
26 #define CONTEXT ((AVCodecContext *)codec)
27
28 #if 0
29 #define xdebug ADM_info
30 #else
31 #define xdebug(...) {}
32 #endif
33
34 static const int aacChannels[16]=
35 {
36 0, //0: Defined in AOT Specifc Config
37 1, //1: 1 channel: front-center
38 2, //2: 2 channels: front-left, front-right
39 3, //3: 3 channels: front-center, front-left, front-right
40 4, //4: 4 channels: front-center, front-left, front-right, back-center
41 5, // 5: 5 channels: front-center, front-left, front-right, back-left, back-right
42 6, // 6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
43 8, // 7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
44 0,0,0,0,
45 0,0,0,0,
46 };
47
48 static uint32_t aacSampleRate[16]=
49 {
50 96000, 88200, 64000, 48000,
51 44100, 32000, 24000, 22050,
52 16000, 12000, 11025, 8000,
53 0, 0, 0, 0
54 };
55
56
57 /**
58 \fn getExtraData
59 \brief extract extradata from adts/aac stream. You must have converted successfully at leat one frame.
60 */
getExtraData(uint32_t * len,uint8_t ** data)61 bool ADM_latm2aac::getExtraData(uint32_t *len,uint8_t **data)
62 {
63 *data=extraData;
64 *len=extraLen;
65 return true;
66 }
67 /**
68 \fn getFrequency
69 \brief get stream frequency. Convert must have been called ok once.
70 */
getFrequency(void)71 int ADM_latm2aac::getFrequency(void)
72 {
73 return fq;
74 }
75 /**
76 \fn getChannels
77 \brief returns # of channels. Convert must have been called ok once.
78 */
getChannels(void)79 int ADM_latm2aac::getChannels(void)
80 {
81 return channels;
82 }
83 /**
84
85 */
LatmGetValue(getBits & bits)86 static int LatmGetValue( getBits &bits )
87 {
88 int i_bytes = bits.get( 2 );
89 int v = 0;
90 int i;
91 for( i = 0; i < i_bytes; i++ )
92 v = (v << 8) + bits.get(8);
93 return v;
94 }
read31plus(getBits & bits)95 static int read31plus(getBits &bits)
96 {
97 int type=bits.get(5);
98 if(type==31)
99 type=32+bits.get(6);
100 return type;
101 }
102 /**
103 \fn AudioSpecificConfig
104 */
AudioSpecificConfig(getBits & bits,int & bitsConsumed)105 bool ADM_latm2aac::AudioSpecificConfig(getBits &bits,int &bitsConsumed)
106 {
107 int consumed=bits.getConsumedBits();
108 getBits myBits(bits); // get a copy, needed to extract extra data
109
110
111 int audioObjectType=read31plus(bits);
112 int samplingFrequencyIndex=bits.get(4);
113
114 if(samplingFrequencyIndex==0xf)
115 {
116 fq=(bits.get(8)<<16)+bits.get(16);
117 }else
118 {
119 fq=aacSampleRate[samplingFrequencyIndex];
120 }
121 int channelConfiguration=bits.get(4);
122 channels=aacChannels[channelConfiguration];
123 xdebug("Fq=%d, channel=%d\n",fq,channelConfiguration);
124 xdebug("ObjectType=%d\n",audioObjectType);
125
126 if(audioObjectType==5) // SBR
127 {
128 int extendedSamplingFrequencyIndex=bits.get(4);
129 xdebug("SBR audio freq=%d\n",aacSampleRate[extendedSamplingFrequencyIndex]);
130
131 audioObjectType=read31plus(bits); // 5 bits
132 xdebug("New object type=%d\n",audioObjectType);
133 }
134 //17
135 switch(audioObjectType)
136 {
137 case 2: // GASpecificConfig
138 {
139 int frameLengthFlags=bits.get(1); // frameLength
140 bool dependsOnCoreCoder=bits.get(1);
141 xdebug("FrameLengthFlags=%d\n",frameLengthFlags);
142 xdebug("dependsOnCoreCoder=%d\n",dependsOnCoreCoder);
143 if(dependsOnCoreCoder) bits.skip(14); // coreCoderDelay
144 bool extensionFlag=bits.get(1); //23
145 if(!channelConfiguration)
146 {
147 ADM_error("No channel configuraiton\n");
148 return false;
149 }
150 if(extensionFlag)
151 {
152 ADM_warning("Extension flag\n");
153 //bits.get(1); // extensionFlag3
154 return false;
155 }
156 }
157 break;
158 default:
159 ADM_error("AudioObjecttype =%d not handled\n",audioObjectType);
160 return false;
161 }
162 consumed=bits.getConsumedBits()-consumed;
163 bitsConsumed=consumed;
164 xdebug("%d bits consumed\n",consumed);
165 extraLen=(consumed+7)/8;
166 #if 0 // pad left
167 // fill to get 8 bits..
168 int top=consumed&7;
169 if(!top) top=8;
170 extraData[0]=myBits.get(top);
171 for(int i=1;i<extraLen;i++)
172 {
173 extraData[i]=myBits.get(8);
174 }
175 #else // pad right
176 for(int i=0;i<extraLen;i++)
177 {
178 int rd=consumed;
179 if(rd>8) rd=8;
180 extraData[i]=(myBits.get(rd))<<(8-rd);
181 consumed-=rd;
182 }
183
184 #endif
185
186 xdebug("Got %d extraData \n",extraLen);
187 for(int i=0;i<extraLen;i++)
188 xdebug(" %02x",extraData[i]);
189 xdebug(" \nFrequency %d, channels %d\n",fq,channels);
190 conf.gotConfig=true;
191 return true;
192
193 }
194 /**
195 \fn readPayloadInfoLength
196 */
readPayloadInfoLength(getBits & bits)197 int ADM_latm2aac::readPayloadInfoLength(getBits &bits)
198 {
199 if(conf.allStreamsSameTimeFraming)
200 {
201 // handle layer..., only one accepted ATM
202 if(conf.frameLengthType[0]==0)
203 {
204 int l=0;
205 while(1)
206 {
207 int tmp=bits.get(8);
208 l+=tmp;
209 if(tmp!=255) break;
210 }
211 xdebug("Payload Len=%d\n",l);
212 return l;
213 }
214 }else
215 {
216 ADM_error("cannot handle allStreamSameTimeFraming==0\n");
217
218 }
219 return 0;
220 }
221 /**
222 \fn readPayload
223 */
readPayload(getBits & bits,uint64_t dts,int size)224 bool ADM_latm2aac::readPayload(getBits &bits, uint64_t dts,int size)
225 {
226 if(conf.allStreamsSameTimeFraming)
227 {
228 xdebug("Payload %d \n",size);
229 if(size>LATM_MAX_BUFFER_SIZE)
230 {
231 ADM_warning("Packet too big %d vs %d\n",size,LATM_MAX_BUFFER_SIZE);
232 return false;
233 }
234
235 // try to get a buffer...
236 if(listOfFreeBuffers.isEmpty())
237 {
238 ADM_error("No free buffer!\n");
239 return false;
240 }
241 latmBuffer *b=listOfFreeBuffers.popBack();
242 b->dts=dts;
243 for(int i=0;i<size;i++)
244 {
245 b->buffer[i]=bits.get(8);
246 }
247 b->bufferLen=size;
248 if(!conf.gotConfig)
249 listOfFreeBuffers.pushBack(b);
250 else
251 listOfUsedBuffers.pushBack(b);
252 return true;
253 }else
254 {
255
256 ADM_error("cannot handle allStreamSameTimeFraming==0\n");
257 return false;
258 }
259 }
260 /**
261 \fn readStreamMuxConfig
262 */
readStreamMuxConfig(getBits & bits)263 bool ADM_latm2aac::readStreamMuxConfig(getBits &bits)
264 {
265 // streamMuxConfig
266 conf.audioMuxVersion = bits.get(1);
267 if(conf.audioMuxVersion==1)
268 conf.audioMuxVersionA = bits.get(1);
269 if( conf.audioMuxVersionA != 0 ) /* support only A=0 */
270 {
271 ADM_warning("LATM : versionA!=0, not supported\n");
272 return false;
273 }
274
275 if( conf.audioMuxVersion == 1 )
276 {
277 LatmGetValue(bits); /* taraBufferFullness */
278 }
279
280 conf.allStreamsSameTimeFraming=bits.get(1);
281 xdebug("AllSTreamSameTimeFraming =%d\n",conf.allStreamsSameTimeFraming);
282 int numSubFrames=bits.get(6)+1;
283 int numbSubProgram=1+bits.get(4);
284
285 xdebug("NumSubFrame=%d, numSubProgram=%d\n",numSubFrames,numbSubProgram);
286
287 if(numSubFrames!=1 || numbSubProgram!=1 )
288 {
289 ADM_warning("LATM: only supports subframe=1, subprogram=1\n");
290 return false;
291 }
292
293 conf.nbLayers=1+bits.get(3);
294 xdebug("NumLayer=%d\n",conf.nbLayers);
295
296 for(int i=0;i<conf.nbLayers;i++)
297 {
298 bool useSameConfig=false;
299
300 if(i)
301 useSameConfig=bits.get(1);
302 if(!useSameConfig)
303 {
304 int consumed=0;
305
306 if(!conf.audioMuxVersion)
307 { // audio specific config
308 if(false==AudioSpecificConfig(bits,consumed))
309 {
310 ADM_warning("Error reading audioSpecificConfig\n");
311 return false;
312 }
313
314 }else
315 {
316 int ascLen=LatmGetValue(bits);
317
318 //ascLen-=audioSpecicConfig
319 //fillBits(ascLen)
320 if(false==AudioSpecificConfig(bits,consumed))
321 {
322 ADM_warning("Error reading audioSpecificConfig\n");
323 return false;
324 }
325 if(consumed>ascLen)
326 {
327 ADM_warning("Too much bits consumed in AudioSpecificConfig (%d/%d)\n",consumed,ascLen);
328 return false;
329 }
330 ascLen-=consumed;
331 while(ascLen)
332 {
333 int r=ascLen;
334 if(r>16) r=16;
335 bits.skip(r);
336 ascLen-=r;
337 }
338 }
339 }
340 // frameLengthType
341 conf.frameLengthType[i]=bits.get(3);
342 xdebug("FrameLengthType=%d\n",conf.frameLengthType[i]);
343 if(conf.frameLengthType[i]!=0)
344 {
345 ADM_error("frameLengthType!=0 not supported (%d)\n",conf.frameLengthType[i]);
346 return false;
347 }
348
349 bits.get(8); // latmBufferFulless
350
351 int otherData=bits.get(1);
352
353 if(otherData)
354 {
355 int otherDataLen=0;
356
357 if(conf.audioMuxVersion==1)
358 otherDataLen=LatmGetValue(bits);
359 else
360 {
361 while(1)
362 {
363 int esc=bits.get(1);
364 int data=bits.get(8);
365 otherDataLen=(otherDataLen<<8)+data;
366 if(!esc) break;
367 }
368 }
369
370 }
371 int crc=bits.get(1);
372 if(crc) bits.get(8);
373 }
374 return true;
375 }
376 /**
377 \fn readStreamMux
378 \brief from vlc
379 */
readAudioMux(uint64_t dts,getBits & bits)380 bool ADM_latm2aac::readAudioMux( uint64_t dts,getBits &bits )
381 {
382
383 if( !bits.get(1) ) // use SameStreamMux
384 {
385 if(false==readStreamMuxConfig(bits))
386 {
387 return false;
388 }
389 } // streamMuxConfig
390 // if(!numSubFrames) return false;
391 if(conf.audioMuxVersionA==0)
392 {
393 // only 1 subFrames ATM... for(int i=0;i<numSubFrames;i++)
394 {
395 int len=readPayloadInfoLength(bits);
396 if(!len) return false;
397
398 bool r=readPayload(bits,dts,len);
399 bits.align();
400 return r;
401 }
402 // otherdata
403 }
404 return true;
405 }
406
407
408
409 /**
410 \fn demuxLatm
411 \brief extract extrdata + aac frame from LATM
412 */
demuxLatm(uint64_t date,uint8_t * start,uint32_t size)413 bool ADM_latm2aac::demuxLatm(uint64_t date,uint8_t *start,uint32_t size)
414 {
415 getBits bits(size+AV_INPUT_BUFFER_PADDING_SIZE,start);
416 return readAudioMux(date,bits);
417 }
418 /**
419 \fn pushData
420 \brief Check for LOAS sync word, extract LATM frames
421 */
422
pushData(int incomingLen,uint8_t * inData)423 bool ADM_latm2aac::pushData(int incomingLen,uint8_t *inData)
424 {
425 xdebug("Pushing data %d bytes\n",incomingLen);
426 // Compact incoming buffer
427 if(head==tail)
428 {
429 head=tail=0;
430 }
431 if(tail>INCOMING_BUFFER_SIZE>>1)
432 {
433 int size=head-tail;
434 memmove(depot.at(0),depot.at(tail),size);
435 head=size;
436 tail=0;
437 }
438 if(head+incomingLen>INCOMING_BUFFER_SIZE)
439 {
440 ADM_error("LATM incoming buffer overflow: incoming: %d available: %d\n",incomingLen,INCOMING_BUFFER_SIZE-head);
441 return false;
442 }
443 // Add data
444 memcpy(depot.at(head),inData,incomingLen);
445 head+=incomingLen;
446 memset(depot.at(head),0,AV_INPUT_BUFFER_PADDING_SIZE);
447 return true;
448 }
449 /**
450 \fn convert
451 \brief find LATM frame in the incoming buffer and demux it
452 */
convert(uint64_t dts)453 ADM_latm2aac::LATM_STATE ADM_latm2aac::convert(uint64_t dts)
454 {
455 if(head==tail)
456 return LATM_MORE_DATA_NEEDED;
457 // Lookup sync
458 uint8_t *start=depot.at(tail);
459 uint8_t *end=depot.at(head);
460 uint32_t len=0;
461 while(start+2<end)
462 {
463 int key=(start[0]<<8)+start[1];
464 if((key & 0xffe0)!=0x56e0) // 0x2b7 shifted by one bit
465 {
466 start++;
467 tail++;
468 continue;
469 }
470 len=start[2]+((key & 0x1f)<<8);
471 start+=3;
472 if(start+len>end)
473 {
474 xdebug("Not enough data, need %d, got %d\n",len,(int)(end-start));
475 int size=head-tail;
476 memmove(depot.at(0),depot.at(tail),size);
477 tail=0;
478 head=size;
479 return LATM_MORE_DATA_NEEDED;
480 }
481 break;
482 }
483 if(!len)
484 {
485 xdebug("No sync.\n");
486 return LATM_MORE_DATA_NEEDED;
487 }
488 xdebug("Found LATM : size %d\n",len);
489 // Demux one LATM frame
490 bool r = demuxLatm(dts,start,len);
491 tail+=len;
492 ADM_assert(head>=tail);
493 xdebug("-- end of this LATM frame --\n");
494 return r? LATM_OK : LATM_ERROR;
495 }
496 /**
497 \fn ctor
498 */
499
ADM_latm2aac(void)500 ADM_latm2aac::ADM_latm2aac(void)
501 {
502 fq=0;
503 channels=0;
504 extraLen=0;
505 memset(&conf,0,sizeof(conf));
506 conf.gotConfig=false;
507 for(int i=0;i<LATM_NB_BUFFERS;i++)
508 listOfFreeBuffers.pushBack(&(buffers[i]));
509 depot.setSize(INCOMING_BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE);
510 head=tail=0;
511 }
512 /**
513 \fn dtor
514 */
515
~ADM_latm2aac()516 ADM_latm2aac::~ADM_latm2aac()
517 {
518 }
519
520 /**
521 \fn empty
522 \brief returns true if output packet queue is empty
523 */
empty()524 bool ADM_latm2aac::empty()
525 {
526 if(listOfUsedBuffers.isEmpty()) return true;
527 return false;
528 }
529
530 /**
531 \fn flush
532 \brief flush packet queue. Must be called when seeking
533 */
flush()534 bool ADM_latm2aac::flush()
535 {
536 listOfFreeBuffers.clear();
537 listOfUsedBuffers.clear();
538 for(int i=0;i<LATM_NB_BUFFERS;i++)
539 listOfFreeBuffers.pushBack(&(buffers[i]));
540 head=tail=0;
541 return true;
542 }
543 /**
544 \fn getData
545 \brief pop one packet from packet queue
546 */
getData(uint64_t * time,uint32_t * len,uint8_t * data,uint32_t maxSize)547 bool ADM_latm2aac::getData(uint64_t *time,uint32_t *len, uint8_t *data, uint32_t maxSize)
548 {
549 if(empty()) return false;
550 // xdebug("%d slogs in latm buffers\n",listOfUsedBuffers.size());
551 latmBuffer *b=listOfUsedBuffers.pop();
552 listOfFreeBuffers.pushBack(b);
553 if(b->bufferLen>maxSize)
554 {
555 ADM_warning("Buffer too small\n");
556 return false;
557
558 }
559 memcpy(data,b->buffer.at(0),b->bufferLen);
560 *len=b->bufferLen;
561 b->bufferLen=0;
562 *time=b->dts;
563 xdebug(" read %d bytes\n",*len);
564 return true;
565 }
566 //EOF
567