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