1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18#include "latmpayloadparser.h"
19
20#include "e_tmp4audioobjecttype.h"
21#include "e_mp4ff_const.h"
22#include "e_progconfigconst.h"
23#include "e_rawbitstreamconst.h"
24#ifndef OSCL_EXCLUSIVE_PTR_H_INCLUDED
25#include "oscl_exclusive_ptr.h"
26#endif
27
28#define MAX_NUM_COMPOSITE_FRAMES            32
29/* Mempool size of latm parser should be at least 1 more than OMX component
30   mempool size, which is 10 */
31#define PVLATMPARSER_MEDIADATA_POOLNUM      12
32#define PVLATMPARSER_LATMDATA_CHUNKSIZE     1536*10 // 10 maximum aac frames
33#define PVLATMPARSER_MEDIADATA_CHUNKSIZE    128
34
35static uint32 BufferShowBits(uint8 *inbuf, uint32 pos1, uint32 pos2);
36static uint32 BufferReadBits(uint8 *inbuf, uint32 *pos1, int32 len);
37
38
39#ifndef OSCL_DLL_H_INCLUDED
40#include "oscl_dll.h"
41#endif
42
43// Define entry point for this DLL
44OSCL_DLL_ENTRY_POINT_DEFAULT()
45
46
47OSCL_EXPORT_REF PV_LATM_Parser::PV_LATM_Parser() :
48        last_timestamp(0),
49        last_mbit(0),
50        offset(0),
51        framestart(false),
52        framesize(0),
53        currLen(0),
54        firstBlock(true),
55        bytesRead(0),
56        myBool(false),
57        frameNum(0),
58        compositenumframes(0),
59        iMediaDataSimpleAlloc(&iLATMDataMemPool),
60        iLATMDataMemPool(PVLATMPARSER_MEDIADATA_POOLNUM, PVLATMPARSER_LATMDATA_CHUNKSIZE),
61        iMediaDataMemPool(PVLATMPARSER_MEDIADATA_POOLNUM, PVLATMPARSER_MEDIADATA_CHUNKSIZE),
62        sMC(NULL),
63        // used only for composemultipleframe, allow at least 4 AAC frames
64        currSize(PVLATMPARSER_LATMDATA_CHUNKSIZE),
65        firstPacket(true),
66        dropFrames(false),
67        firstSMC(true),
68        startedParsing(false),
69        framePos(NULL),
70        frameCount(0)
71{
72    multiFrameBuf = (uint8 *) oscl_calloc(currSize, sizeof(uint8));
73
74    // calculate a max frame size to check if the latm parser gets out of sync
75    maxFrameSize = currSize; // currently allows 4 max length case AAC frames
76
77    iOsclErrorTrapImp = OsclErrorTrap::GetErrorTrapImp();
78}
79
80
81OSCL_EXPORT_REF PV_LATM_Parser::~PV_LATM_Parser()
82{
83    if (sMC != NULL)
84    {
85        if (sMC->audioSpecificConfigPtr != NULL)
86        {
87            oscl_free(sMC->audioSpecificConfigPtr);
88            sMC->audioSpecificConfigPtr = NULL;
89        }
90        oscl_free(sMC);
91        sMC = NULL;
92    }
93    if (multiFrameBuf != NULL)
94    {
95        oscl_free(multiFrameBuf);
96        multiFrameBuf = NULL;
97    }
98
99    mediaDataOut.Unbind();
100}
101
102
103/* ======================================================================== */
104/*  Function : compose()                                                    */
105/*  Purpose  : parse AAC LATM payload                                       */
106/*  In/out   :                                                              */
107/*  Return   :                                                              */
108/*  Note     :                                                              */
109/*  Modified :                                                              */
110/* ======================================================================== */
111
112OSCL_EXPORT_REF uint8 PV_LATM_Parser::compose(PVMFSharedMediaDataPtr& mediaDataIn)
113{
114    uint8 retVal = 0;
115
116    OsclRefCounterMemFrag memFragIn;
117    mediaDataIn->getMediaFragment(0, memFragIn);
118
119    // Don't need the ref to iMediaData so unbind it
120    mediaDataOut.Unbind();
121
122    int errcode = 0;
123    OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl;
124    OSCL_TRY_NO_TLS(iOsclErrorTrapImp, errcode, mediaDataImpl = iMediaDataSimpleAlloc.allocate((uint32)memFragIn.getMemFrag().len));
125    OSCL_FIRST_CATCH_ANY(errcode, return FRAME_OUTPUTNOTAVAILABLE);
126
127    errcode = 0;
128    OSCL_TRY_NO_TLS(iOsclErrorTrapImp, errcode, mediaDataOut = PVMFMediaData::createMediaData(mediaDataImpl, &iMediaDataMemPool));
129    OSCL_FIRST_CATCH_ANY(errcode, return FRAME_OUTPUTNOTAVAILABLE);
130
131    OsclRefCounterMemFrag memFragOut;
132    mediaDataOut->getMediaFragment(0, memFragOut);
133
134    /*
135     *  Latch for very first packet, sequence number is not established yet.
136     */
137    int32 seqNum = mediaDataIn->getSeqNum();
138
139    if (!firstPacket)
140    {
141        if ((seqNum - last_sequence_num) > 1)    /* detect any gap in sequence */
142        {
143            // means we missed an RTP packet.
144            dropFrames = true;
145        }
146    }
147    else
148    {
149        firstPacket = false;
150    }
151
152    last_timestamp = mediaDataIn->getTimestamp();
153    last_sequence_num = seqNum;
154    last_mbit = mediaDataIn->getMarkerInfo();
155
156    if (dropFrames)
157    {
158        if (mediaDataIn->getMarkerInfo())
159        {
160            /*
161             *  try to recover packet as sequencing was broken, new packet could be valid
162             *  it is possible that the received packet contains a complete audioMuxElement()
163             *  so try to retrieve it.
164             */
165
166            dropFrames = false;
167        }
168        else
169        {
170
171            /*
172             *  we are in the middle of a spread audioMuxElement(), or faulty rtp header
173             *  return error
174             */
175
176            framesize = 0;
177            frameNum = 0;
178            bytesRead = 0;
179            compositenumframes = 0;
180
181            /*
182             *  Drop frame as we are not certain if it is a valid frame
183             */
184            memFragOut.getMemFrag().len = 0;
185            mediaDataOut->setMediaFragFilledLen(0, 0);
186
187            firstBlock = true; // set for next call
188            return FRAME_ERROR;
189        }
190    }
191
192
193    if (sMC->numSubFrames > 0 || (sMC->cpresent == 1 && ((*(uint8*)(memFragIn.getMemFrag().ptr)) &(0x80))))
194    {
195        // this is a less efficient version that must be used when you know an AudioMuxElement has
196        // more than one subFrame -- I also added the case where the StreamMuxConfig is inline
197        // The reason for this is that the StreamMuxConfig can be possibly large and there is no
198        // way to know its size without parsing it. (the problem is it can straddle an RTP boundary)
199        // it is less efficient because it composes the AudioMuxElement in a separate buffer (one
200        // oscl_memcpy() per rtp packet) then parses it (one oscl_memcpy() per audio frame to the output
201        // buffer (newpkt->outptr)) when it gets a whole AudioMuxElement.
202        // The function below does a oscl_memcpy() directly into the output buffer
203        // note, composeMultipleFrame will also work for the simple case in case there is another reason
204        // to have to use it..
205
206        retVal = composeMultipleFrame(mediaDataIn);
207    }
208    else
209    {
210        // this is an efficient version that can be used when you know an AudioMuxElement has
211        // only one subFrame
212        retVal = composeSingleFrame(mediaDataIn);
213    }
214
215    // set this to drop frames in the future -- till we find another marker bit
216    if (retVal == FRAME_ERROR)
217    {
218        dropFrames = true;
219
220        framesize = 0;
221        frameNum = 0;
222        bytesRead = 0;
223        compositenumframes = 0;
224
225        //changed
226        memFragOut.getMemFrag().len = 0;
227        mediaDataOut->setMediaFragFilledLen(0, 0);
228
229        firstBlock = true; // set for next call
230
231    }
232    return retVal;
233}
234
235OSCL_EXPORT_REF uint8 PV_LATM_Parser::compose(uint8* aData, uint32 aDataLen, uint32 aTimestamp, uint32 aSeqNum, uint32 aMbit)
236{
237    uint8 retVal = 0;
238
239    // Don't need the ref to iMediaData so unbind it
240    mediaDataOut.Unbind();
241
242    int errcode = 0;
243    OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl;
244    OSCL_TRY_NO_TLS(iOsclErrorTrapImp, errcode, mediaDataImpl = iMediaDataSimpleAlloc.allocate(aDataLen));
245    OSCL_FIRST_CATCH_ANY(errcode, return FRAME_OUTPUTNOTAVAILABLE);
246
247    errcode = 0;
248    OSCL_TRY_NO_TLS(iOsclErrorTrapImp, errcode, mediaDataOut = PVMFMediaData::createMediaData(mediaDataImpl, &iMediaDataMemPool));
249    OSCL_FIRST_CATCH_ANY(errcode, return FRAME_OUTPUTNOTAVAILABLE);
250
251    OsclRefCounterMemFrag memFragOut;
252    mediaDataOut->getMediaFragment(0, memFragOut);
253
254    /*
255     *  Latch for very first packet, sequence number is not established yet.
256     */
257
258    if (!firstPacket)
259    {
260        if ((aSeqNum - last_sequence_num) > 1)    /* detect any gap in sequence */
261        {
262            // means we missed an RTP packet.
263            dropFrames = true;
264        }
265    }
266    else
267    {
268        firstPacket = false;
269    }
270
271    last_timestamp = aTimestamp;
272    last_sequence_num = aSeqNum;
273    last_mbit = aMbit;
274
275    if (dropFrames)
276    {
277        if (last_mbit)
278        {
279            /*
280             *  try to recover packet as sequencing was broken, new packet could be valid
281             *  it is possible that the received packet contains a complete audioMuxElement()
282             *  so try to retrieve it.
283             */
284
285            dropFrames = false;
286        }
287        else
288        {
289
290            /*
291             *  we are in the middle of a spread audioMuxElement(), or faulty rtp header
292             *  return error
293             */
294
295            framesize = 0;
296            frameNum = 0;
297            bytesRead = 0;
298            compositenumframes = 0;
299
300            /*
301             *  Drop frame as we are not certain if it is a valid frame
302             */
303            memFragOut.getMemFrag().len = 0;
304            mediaDataOut->setMediaFragFilledLen(0, 0);
305
306            firstBlock = true; // set for next call
307            return FRAME_ERROR;
308        }
309    }
310
311
312    if (sMC->numSubFrames > 0 || (sMC->cpresent == 1 && ((*aData) & (0x80))))
313    {
314        // this is a less efficient version that must be used when you know an AudioMuxElement has
315        // more than one subFrame -- I also added the case where the StreamMuxConfig is inline
316        // The reason for this is that the StreamMuxConfig can be possibly large and there is no
317        // way to know its size without parsing it. (the problem is it can straddle an RTP boundary)
318        // it is less efficient because it composes the AudioMuxElement in a separate buffer (one
319        // oscl_memcpy() per rtp packet) then parses it (one oscl_memcpy() per audio frame to the output
320        // buffer (newpkt->outptr)) when it gets a whole AudioMuxElement.
321        // The function below does a oscl_memcpy() directly into the output buffer
322        // note, composeMultipleFrame will also work for the simple case in case there is another reason
323        // to have to use it..
324
325        retVal = composeMultipleFrame(aData, aDataLen, aTimestamp, aSeqNum, aMbit);
326    }
327    else
328    {
329        // this is an efficient version that can be used when you know an AudioMuxElement has
330        // only one subFrame
331        retVal = composeSingleFrame(aData, aDataLen, aTimestamp, aSeqNum, aMbit);
332    }
333
334    // set this to drop frames in the future -- till we find another marker bit
335    if (retVal == FRAME_ERROR)
336    {
337        dropFrames = true;
338
339        framesize = 0;
340        frameNum = 0;
341        bytesRead = 0;
342        compositenumframes = 0;
343
344        //changed
345        memFragOut.getMemFrag().len = 0;
346        mediaDataOut->setMediaFragFilledLen(0, 0);
347
348        firstBlock = true; // set for next call
349
350    }
351    return retVal;
352}
353/* ======================================================================== */
354/*  Function : composeSingleFrame()                                         */
355/*  Purpose  : parse AAC LATM payload                                       */
356/*  In/out   :                                                              */
357/*  Return   :                                                              */
358/*  Note     :                                                              */
359/*  Modified :                                                              */
360/* ======================================================================== */
361
362uint8 PV_LATM_Parser::composeSingleFrame(PVMFSharedMediaDataPtr& mediaDataIn)
363{
364    int32 tmp = 0;
365
366    //changed
367    OsclRefCounterMemFrag memFragIn;
368    mediaDataIn->getMediaFragment(0, memFragIn);
369
370    // pool made for output data
371    OsclRefCounterMemFrag memFragOut;
372    mediaDataOut->getMediaFragment(0, memFragOut);
373
374    //uint8 * myData = newpkt->data;
375    uint8 * myData = (uint8*)memFragIn.getMemFrag().ptr;
376
377    /*
378     *  Total Payload length, in bytes, includes
379     *      length of the AudioMuxElement()
380     *      AudioMuxElement()
381     *      Other data (for RF3016 not supported)
382     */
383    int32 pktsize = memFragIn.getMemFrag().len;
384
385    int32 m_bit = mediaDataIn->getMarkerInfo();
386
387    /*
388     *  All streams have same time framing (there is only one stream anyway)
389     */
390    if (firstBlock)
391    {
392        /*
393         *  AudioMuxElement() fits in a single rtp packet or this is the first
394         *  block of an AudioMuxElement() spread accross more than one rtp packet
395         */
396
397
398        int32 bUsed = 0;
399
400        /*
401         *      PayLoadlenghtInfo( )
402         */
403
404        do
405        {
406            tmp = *(myData++);      /* get payload lenght  8-bit in bytes */
407            framesize += tmp;
408            bUsed++;
409        }
410        while (tmp == 0xff);      /* 0xff is the escape sequence for values bigger than 255 */
411
412
413        /*
414         *      PayLoadMux( )
415         */
416
417        bytesRead = (pktsize - bUsed);
418
419        // framesize must be equal to the bytesRead if mbit is 1
420        // or greater than bytesRead if mbit is 0
421        if ((m_bit && framesize != bytesRead && !sMC->otherDataPresent) ||
422                (!m_bit && framesize < bytesRead && !sMC->otherDataPresent))
423        {
424            // to update number of bytes copied
425            memFragOut.getMemFrag().len = 0;
426            mediaDataOut->setMediaFragFilledLen(0, 0);
427            bytesRead = 0;
428
429            return FRAME_ERROR;
430        }
431
432        oscl_memcpy((uint8*)memFragOut.getMemFrag().ptr, myData, bytesRead); //ptr +1 changed
433
434        if (sMC->otherDataPresent)
435        {
436            ;   /* dont' care at this point, no MUX other than aac supported */
437        }
438
439    }
440    else
441    {
442        /*
443         *  We have an AudioMuxElement() spread accross more than one rtp packet
444         */
445        if ((m_bit && framesize != pktsize + (bytesRead - 1) && !sMC->otherDataPresent) /* last block */ ||
446                (!m_bit && framesize <  pktsize + (bytesRead - 1) && !sMC->otherDataPresent) /* intermediate block */)
447        {
448
449            // to update number of bytes copied
450            memFragOut.getMemFrag().len = 0;
451            mediaDataOut->setMediaFragFilledLen(0, 0);
452
453            return FRAME_ERROR;
454        }
455
456        /*
457         *  Accumulate  blocks until the full frame is complete
458         */
459        oscl_memcpy((uint8*)memFragOut.getMemFrag().ptr + bytesRead, myData, pktsize);
460        bytesRead += pktsize;
461    }
462
463
464    // to update number of bytes copied
465    memFragOut.getMemFrag().len = bytesRead;
466    mediaDataOut->setMediaFragFilledLen(0, bytesRead);
467    mediaDataOut->setSeqNum(mediaDataIn->getSeqNum());
468    mediaDataOut->setTimestamp(mediaDataIn->getTimestamp());
469
470
471    firstBlock = false;     /* we already processed the first block, so this should be false  */
472
473    if (m_bit)              /* check if it is a complete packet (m bit ==1) */
474    {
475        firstBlock = true;  /* if m-bit is "1", then the farme fits in a block or this was the last
476                               block of the frame, set for next call */
477        framesize = 0;
478        frameNum = 0;
479        bytesRead = 0;
480        compositenumframes = 0;
481    }
482    else
483    {
484        /*
485         *  We have an AudioMuxElement() spread accross more than one rtp packet
486         */
487        compositenumframes++;
488
489        if (compositenumframes < MAX_NUM_COMPOSITE_FRAMES)
490        {
491            // this is not yet a finished packet
492            return FRAME_INCOMPLETE;
493        }
494        else
495        {
496            return FRAME_ERROR;
497        }
498
499    }
500    return FRAME_COMPLETE;
501}
502
503
504// this below is to choose between a version that returns blocks of frames
505// to the cadi, or buffers those frames and returns one at a time
506// set to 1 for original version that returns blocks of frames
507// set to 0 for new version that buffers and returns only one frame per call
508
509
510/* ======================================================================== */
511/*  Function : composeMulitpleFrame()                                       */
512/*  Purpose  : parse AAC LATM payload                                       */
513/*  In/out   :                                                              */
514/*  Return   :                                                              */
515/*  Note     :                                                              */
516/*  Modified :                                                              */
517/* ======================================================================== */
518uint8 PV_LATM_Parser::composeMultipleFrame(PVMFSharedMediaDataPtr& mediaDataIn)
519{
520
521    uint32 tmp;
522    uint8 * myData;
523    uint32 i;
524
525
526    OsclRefCounterMemFrag memFragIn;
527    mediaDataIn->getMediaFragment(0, memFragIn);
528
529    // pool made for output data
530    OsclRefCounterMemFrag memFragOut;
531    mediaDataOut->getMediaFragment(0, memFragOut);
532
533    int32 pktsize = memFragIn.getMemFrag().len;
534
535    // make sure we have enough memory to hold the data
536    if (bytesRead + pktsize > currSize)
537    {
538        uint8 * tempPtr = (uint8*) oscl_calloc(bytesRead + pktsize, sizeof(uint8));
539        if (tempPtr == NULL)
540        {
541            // memory problem?
542            return FRAME_ERROR;
543        }
544        currSize = bytesRead + pktsize;
545        oscl_memcpy(tempPtr, multiFrameBuf, bytesRead);
546        oscl_free(multiFrameBuf);
547        multiFrameBuf = tempPtr;
548    }
549
550    oscl_memcpy(multiFrameBuf + bytesRead, memFragIn.getMemFrag().ptr, pktsize);
551
552    bytesRead += pktsize;
553    //newpkt->frame_size = bytesRead;
554
555    // to update number of bytes copied
556    memFragOut.getMemFrag().len = bytesRead;
557    mediaDataOut->setMediaFragFilledLen(0, bytesRead);
558    mediaDataOut->setSeqNum(mediaDataIn->getSeqNum());
559    mediaDataOut->setTimestamp(mediaDataIn->getTimestamp());
560
561    if (mediaDataIn->getMarkerInfo())
562    {
563        // means this is the last packet for this audioMuxElement
564
565        myData = multiFrameBuf;
566
567        uint32 outPtrPos = 0;
568        for (i = 0; i <= sMC->numSubFrames; i++)
569        {
570            framesize = 0;
571            do
572            {
573                tmp = *(myData);
574                framesize += tmp;
575            }
576            while (*(myData++) == 0xff);
577
578            //int32 bUsed = (framesize/255)+1; // 0-254: 1, 255-511: 2 ...
579            // do a check on the last one
580            if (i == sMC->numSubFrames && !sMC->otherDataPresent)
581            {
582                if (framesize != bytesRead - (myData - multiFrameBuf))
583                {
584                    // to update number of bytes copied
585                    memFragOut.getMemFrag().len = 0;
586                    mediaDataOut->setMediaFragFilledLen(0, 0);
587
588                    return FRAME_INCOMPLETE;
589                }
590            }
591            oscl_memcpy((uint8*)memFragOut.getMemFrag().ptr + outPtrPos, myData, framesize);
592            myData += framesize;
593            outPtrPos += framesize;
594        }
595
596
597
598        // to update number of bytes copied
599        memFragOut.getMemFrag().len = outPtrPos;
600        mediaDataOut->setMediaFragFilledLen(0, outPtrPos);
601
602        bytesRead = 0;
603        framesize = 0;
604        compositenumframes = 0;
605
606    }
607    else
608    {
609        compositenumframes++;
610
611        if (compositenumframes < MAX_NUM_COMPOSITE_FRAMES)
612        {
613            return FRAME_INCOMPLETE;
614        }
615        else
616        {
617            return FRAME_ERROR;
618        }
619
620    }
621
622    return FRAME_COMPLETE;
623}
624
625///////////////////////////////////Create a function to decode the StreamMuxConfig
626// note this function should ideally also get a reference to an object that holds the values
627// for the streammuxconfig... these are alse needed in the mediaInfo class (to pass to
628// the parser constructor) and can be gotten here.  for now just get the audiospecificconfig
629OSCL_EXPORT_REF uint8 * PV_LATM_Parser::ParseStreamMuxConfig(uint8* decoderSpecificConfig, int32 * size)
630{
631    uint32 SMC_SUCCESS = 0;
632    uint32 SMC_INVALID_MUX_VERSION = 1;
633    uint32 SMC_INVALID_NUM_PROGRAM = 2;
634    uint32 SMC_INVALID_NUM_LAYER = 4;
635    uint32 SMC_INVALID_OBJECT_TYPE = 8;
636    uint32 SMC_USED_RESERVED_SAMPLING_FREQ = 16;
637
638    uint32 samplingFreqTable[] =
639    {
640        96000, 88200, 64000, 48000, 44100,
641        32000, 24000, 22050, 16000, 12000,
642        11025, 8000, 7350
643    };
644
645    if (*size == 0)
646    {
647        // means there is nothing to parse
648        return NULL;
649    }
650
651
652    // size should be the length of the decoderSpecificConfig.. the AudioSpecificConfing cant
653    // be larger than that, so just allocate that number of bytes
654    // we wont know until we've parsed it how big it is.
655    OsclMemAllocator alloc;
656    uint8* ASCPtr = (uint8*)(alloc.allocate(sizeof(uint8) * (*size)));
657    if (ASCPtr == NULL)
658    {
659        // memory allocation problem?
660        *size = 0;
661        return NULL;
662    }
663    oscl_memset(ASCPtr, 0, *size);
664
665    OsclExclusivePtrA<uint8, OsclMemAllocator> ascAutoPtr;
666    ascAutoPtr.set(ASCPtr);
667
668    //streamMuxConfig * sMC;
669    sMC = (streamMuxConfig *) oscl_calloc(1, sizeof(streamMuxConfig));
670    if (sMC == NULL)
671    {       // unlikely: calloc failure
672        return NULL;
673    }
674
675
676    sMC->parseResult = SMC_SUCCESS;  // set default result
677
678    uint32 bitPos = 0;
679    uint32 ASCPos = 0;
680
681    int32 temp;
682    int32 numProgram = 0;
683    int32 prog, lay;
684    int32 numLayer;
685    int32 count;
686    int32 dependsOnCoreCoder;
687
688    // audio mux version
689    sMC->audioMuxVersion = BufferReadBits(decoderSpecificConfig, &bitPos, 1);
690    if (sMC->audioMuxVersion == 0)
691    {
692        // should not be anything other than 0!!
693
694        // all streams same time framing
695        sMC->allStreamsSameTimeFraming = BufferReadBits(decoderSpecificConfig, &bitPos, 1);
696
697        /*
698         *  numSubFrames -- how many payloadmux() are multiplexed
699         */
700        sMC->numSubFrames = BufferReadBits(decoderSpecificConfig, &bitPos, 6);
701
702        /*
703         *  numPrograms  -- how many programs are multiplexed
704         */
705        numProgram = BufferReadBits(decoderSpecificConfig, &bitPos, 4);
706
707        if (numProgram != 0)
708        {
709            sMC->parseResult |= SMC_INVALID_NUM_PROGRAM;
710            //numProgram = 0;
711            // really should exit
712            *size = 0;
713            return NULL;
714        }
715
716        // loop through programs -- happens only once now
717        for (prog = 0; prog <= numProgram; prog++)
718        {
719            // can only be one numProgram (RFC3016)
720            numLayer = BufferReadBits(decoderSpecificConfig, &bitPos, 3);
721            /*
722             *  Number of scalable layers, only one is indicated in rfc3016
723             */
724            if (numLayer != 0)
725            {
726                sMC->parseResult |= SMC_INVALID_NUM_LAYER;
727                //numLayer = 0;
728                // really should exit
729                *size = 0;
730                return NULL;
731            }
732
733            for (lay = 0; lay <= numLayer; lay++)
734            {
735                //  can only be one numLayer (RFC3016)
736                if (prog == 0 && lay == 0)
737                {
738                    /*
739                     *  audioSpecificConfig
740                     *
741                     * it starts at byte 1's last (lsb) bit
742                     * basically copy all the rest of the bytes into the ASCPtr
743                     * then shift these over to be byte aligned
744                     */
745                    ASCPos = bitPos;
746
747                    sMC->audioObjectType = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_OBJ_TYPE);
748
749                    if (sMC->audioObjectType != MP4AUDIO_AAC_LC &&
750                            sMC->audioObjectType != MP4AUDIO_LTP &&
751                            sMC->audioObjectType != MP4AUDIO_PS &&
752                            sMC->audioObjectType != MP4AUDIO_SBR)
753                    {
754                        sMC->parseResult |= SMC_INVALID_OBJECT_TYPE;
755                        *size = 0;
756                        return NULL;
757                    }
758
759
760                    // SamplingFrequencyIndex -- see audio spec for meanings
761                    temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SAMP_RATE_IDX);
762
763                    if (temp == 13 || temp == 14)
764                    {
765                        sMC->parseResult |= SMC_USED_RESERVED_SAMPLING_FREQ;
766                    }
767
768
769                    if (temp <= 12)
770                    {
771                        sMC->samplingFrequency = samplingFreqTable[temp];
772                    }
773
774                    if (temp == 0xf)
775                    {
776                        // means the sampling frequency is specified directly in the next 24 bits
777                        temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SAMP_RATE);
778                    }
779
780                    // ChannelConfiguration
781                    sMC->channelConfiguration = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_CHAN_CONFIG);
782
783                    sMC->sbrPresentFlag = -1;
784
785                    if (sMC->audioObjectType == MP4AUDIO_SBR ||
786                            sMC->audioObjectType == MP4AUDIO_PS)
787                    {
788                        /* to disable explicit backward compatiblity check */
789                        sMC->extensionAudioObjectType = sMC->audioObjectType;
790
791                        sMC->sbrPresentFlag = 1;
792
793                        sMC->extensionSamplingFrequencyIndex = /* extensionSamplingFrequencyIndex */
794                            BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SAMP_RATE_IDX);
795
796                        if (sMC->extensionSamplingFrequencyIndex == 0x0f)
797                        {
798                            /*
799                             * sampling rate not listed in Table 1.6.2,
800                             * this release does not support this
801                             */
802                            sMC->extensionSamplingFrequency =  /* extensionSamplingFrequency */
803                                BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SAMP_RATE);
804                        }
805
806
807                        sMC->audioObjectType =  BufferReadBits(decoderSpecificConfig, &bitPos, LEN_OBJ_TYPE);
808                    }
809
810
811                    if (sMC->audioObjectType == MP4AUDIO_AAC_LC || sMC->audioObjectType == MP4AUDIO_LTP)
812                    {
813                        //  GASpecificConfig
814
815                        // frameLengthFlag
816                        temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_FRAME_LEN_FLAG);
817
818                        // dependsOnCoreCoder
819                        dependsOnCoreCoder = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_DEPEND_ON_CORE);
820
821
822                        if (dependsOnCoreCoder == 1)
823                        {
824                            // means there are 14 more bits of coreCoderDelay
825                            temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_CORE_DELAY);
826                        }
827                        // ExtensionFlag
828                        int extensionFlag = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_EXT_FLAG);
829
830                        if (sMC->channelConfiguration == 0)
831                        {
832                            // there should be a program_config_element
833                            // defined in 4.4.1.1 of 3995 sp4
834                            // note, since we are only parsing this to get the size of the
835                            // audioSpecificConfig, we dont care about the values except to know
836                            // how many loops to do in the parsing process... save these loop
837                            // variables in an array
838                            uint32 loopVars[6] = {0, 0, 0, 0, 0, 0};
839
840                            // dont actually need these values, just increment bit pointer
841                            bitPos += LEN_TAG; //temp = BufferReadBits(ASCPtr, &bitPos, 4); // element_instance_tag
842                            bitPos += LEN_PROFILE; //temp = BufferReadBits(ASCPtr, &bitPos, 2); // object_type
843                            bitPos += LEN_SAMP_IDX; //temp = BufferReadBits(ASCPtr, &bitPos, 4); // sampling frequency index
844                            loopVars[0] = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_NUM_ELE); // num front channel elems
845                            loopVars[1] = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_NUM_ELE); // num side channel elems
846                            loopVars[2] = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_NUM_ELE); // num back channel elems
847                            loopVars[3] = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_NUM_LFE); // num lfe channel elems
848                            loopVars[3] = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_NUM_DAT); // num assoc data elems
849                            loopVars[3] = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_NUM_CCE); // num valid cc elems
850
851                            temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_MIX_PRES); // mono mixdown present
852                            if (temp)
853                            {
854                                bitPos += LEN_NUM_ELE;
855                            }
856                            temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_MIX_PRES); // stereo mixdown present
857                            if (temp)
858                            {
859                                bitPos += LEN_NUM_ELE;
860                            }
861                            temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_MIX_PRES); // matrix mixdown present
862                            if (temp)
863                            {
864                                bitPos += LEN_NUM_DAT;
865                            }
866
867                            bitPos += (loopVars[0] * 5);  // front channel info
868                            bitPos += (loopVars[1] * 5);  // side channel info
869                            bitPos += (loopVars[2] * 5);  // back channel info
870                            bitPos += (loopVars[3] * 4);  // lfe channel info
871                            bitPos += (loopVars[4] * 4);  // assoc data info
872                            bitPos += (loopVars[5] * 5);  // valid cc info
873
874                            // then the spec says byte_alignement() .. need to add bits to byte align
875                            // divide by 8, add 1, multiply by 8.  wont work if already byte aligned
876                            // check with a mod 8
877                            if (bitPos % 8 != 0)
878                            {
879                                bitPos = ((bitPos >> 3) + 1) << 3;
880                            }
881
882                            temp = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_COMMENT_BYTES); // comment field bytes
883                            bitPos += (temp << 3);
884
885                        }
886
887                        // this below obviously cant happen at this point, but show it for clarity's sake
888                        if (sMC->audioObjectType == MP4AUDIO_AAC_SCALABLE ||
889                                sMC->audioObjectType == MP4AUDIO_ER_AAC_SCALABLE)
890                        {
891                        }
892
893                        if (extensionFlag)
894                        {
895                            if (sMC->audioObjectType == MP4AUDIO_ER_BSAC)
896                            {
897                                // cant ever happen here
898                            }
899                            if (sMC->audioObjectType == MP4AUDIO_ER_AAC_LC ||
900                                    sMC->audioObjectType == 18 ||
901                                    sMC->audioObjectType == MP4AUDIO_ER_AAC_LTP ||
902                                    sMC->audioObjectType == MP4AUDIO_ER_AAC_SCALABLE ||
903                                    sMC->audioObjectType == MP4AUDIO_ER_TWINVQ ||
904                                    sMC->audioObjectType == MP4AUDIO_ER_AAC_LD)
905                            {
906                                // cant ever happen here
907                            }
908                            // extensionFlag3 -- theoretically possible -- but should only see in future, if ever
909                            temp = BufferReadBits(decoderSpecificConfig, &bitPos, 1);
910                            if (temp)
911                            {
912                                // tbd in version 3
913                            }
914                        }
915                    }
916                    else
917                    {
918                        sMC->parseResult |= SMC_INVALID_OBJECT_TYPE;
919                        *size = 0;
920                        return NULL;
921                    }
922
923
924
925                    /*
926                     *  SBR tool explicit signaling ( backward compatible )
927                     */
928
929                    if (sMC->extensionAudioObjectType != MP4AUDIO_SBR)
930                    {
931                        int32 syncExtensionType = /* syncExtensionType */
932                            BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SYNC_EXTENSION_TYPE);
933
934                        if (syncExtensionType == 0x2b7)
935                        {
936                            sMC->extensionAudioObjectType = /* extensionAudioObjectType */
937                                BufferReadBits(decoderSpecificConfig, &bitPos, LEN_OBJ_TYPE);
938
939                            if (sMC->extensionAudioObjectType == MP4AUDIO_SBR)
940                            {
941                                /* sbrPresentFlag */
942                                sMC->sbrPresentFlag = BufferReadBits(decoderSpecificConfig, &bitPos, 1);
943
944                                if (sMC->sbrPresentFlag == 1)
945                                {
946                                    sMC->extensionSamplingFrequencyIndex =  /* extensionSamplingFrequencyIndex */
947                                        BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SAMP_RATE_IDX);
948
949                                    if (sMC->extensionSamplingFrequencyIndex == 0x0f)
950                                    {
951                                        /*
952                                         * sampling rate not listed in Table 1.6.2,
953                                         * this release does not support this
954                                         */
955                                        int32 sampling_rate = 0;
956                                        sampling_rate = BufferReadBits(decoderSpecificConfig, &bitPos, LEN_SAMP_RATE);
957
958                                    }
959                                }
960                            }
961                        }
962                        else
963                        {
964                            /*
965                             * Rewind bitstream pointer so that the syncExtensionType reading has no
966                             * effect when decoding raw bitstream
967                             */
968                            bitPos -= LEN_SYNC_EXTENSION_TYPE;
969
970                        }
971                    }
972
973                    // this is the end of the audioSpecificConfig
974
975
976
977                    /*
978                     *  Byte Align
979                     */
980                    int32 ASCLen = bitPos - ASCPos;  // length in bits -- will need to be byte aligned
981                    // change length in bytes
982                    if (ASCLen % 8 == 0)
983                    {
984                        ASCLen >>= 3;
985                    }
986                    else
987                    {
988                        ASCLen = (ASCLen >> 3) + 1;
989                    }
990                    int ASCOffset = ASCPos % 8; // use for masking -- do i need this?
991
992                    if (ASCOffset == 0)
993                    {
994                        oscl_memcpy(ASCPtr, decoderSpecificConfig + ASCPos, ASCLen);
995                    }
996                    else
997                    {
998                        for (count = 0; count < ASCLen; count++)
999                        {
1000                            ASCPtr[count] = (uint8)BufferReadBits(decoderSpecificConfig, &ASCPos, 8);
1001                        }
1002                    }
1003                    *size = ASCLen;
1004
1005
1006                    // go back to using decoderSpecificInfo
1007                    sMC->frameLengthType = BufferReadBits(decoderSpecificConfig, &bitPos, 3);
1008                    if (sMC->frameLengthType == 0)
1009                    {
1010                        sMC->bufferFullness = BufferReadBits(decoderSpecificConfig, &bitPos, 8);
1011                    }
1012
1013                    sMC->otherDataPresent = BufferReadBits(decoderSpecificConfig, &bitPos, 1) ? 1 : 0;
1014                    if (sMC->otherDataPresent)
1015                    {
1016                        do
1017                        {
1018                            temp = BufferReadBits(decoderSpecificConfig, &bitPos, 1); // get escape flag
1019                            bitPos += 8; // skip over data itself
1020                        }
1021                        while (temp == 1);
1022                    }
1023
1024                    sMC->crcCheckPresent = BufferReadBits(decoderSpecificConfig, &bitPos, 1) ? 1 : 0;
1025                    if (sMC->crcCheckPresent)
1026                    {
1027                        bitPos += 8;
1028                    }
1029
1030                    // that should be the end of the stream mux config
1031                }
1032            }
1033        }
1034
1035    }
1036    else
1037    {
1038        // spec says tbd
1039        sMC->parseResult |= SMC_INVALID_MUX_VERSION;
1040        *size = 0;
1041        return NULL;
1042    }
1043
1044    ascAutoPtr.release();
1045    return ASCPtr;
1046}
1047uint8 PV_LATM_Parser::composeSingleFrame(uint8* aData, uint32 aDataLen, uint32 aTimestamp, uint32 aSeqNum, uint32 aMbit)
1048{
1049    int32 tmp = 0;
1050
1051    // pool made for output data
1052    OsclRefCounterMemFrag memFragOut;
1053    mediaDataOut->getMediaFragment(0, memFragOut);
1054
1055    //uint8 * myData = newpkt->data;
1056    uint8 * myData = aData;
1057
1058    /*
1059     *  Total Payload length, in bytes, includes
1060     *      length of the AudioMuxElement()
1061     *      AudioMuxElement()
1062     *      Other data (for RF3016 not supported)
1063     */
1064    int32 pktsize = aDataLen;
1065
1066    int32 m_bit = aMbit;
1067
1068    /*
1069     *  All streams have same time framing (there is only one stream anyway)
1070     */
1071    if (firstBlock)
1072    {
1073        /*
1074         *  AudioMuxElement() fits in a single rtp packet or this is the first
1075         *  block of an AudioMuxElement() spread accross more than one rtp packet
1076         */
1077
1078
1079        int32 bUsed = 0;
1080
1081        /*
1082         *      PayLoadlenghtInfo( )
1083         */
1084
1085        do
1086        {
1087            tmp = *(myData++);      /* get payload lenght  8-bit in bytes */
1088            framesize += tmp;
1089            bUsed++;
1090        }
1091        while (tmp == 0xff);      /* 0xff is the escape sequence for values bigger than 255 */
1092
1093
1094        /*
1095         *      PayLoadMux( )
1096         */
1097
1098        bytesRead = (pktsize - bUsed);
1099
1100        // framesize must be equal to the bytesRead if mbit is 1
1101        // or greater than bytesRead if mbit is 0
1102        if ((m_bit && framesize != bytesRead && !sMC->otherDataPresent) ||
1103                (!m_bit && framesize < bytesRead && !sMC->otherDataPresent))
1104        {
1105            // to update number of bytes copied
1106            memFragOut.getMemFrag().len = 0;
1107            mediaDataOut->setMediaFragFilledLen(0, 0);
1108            bytesRead = 0;
1109
1110            return FRAME_ERROR;
1111        }
1112
1113        oscl_memcpy((uint8*)memFragOut.getMemFrag().ptr, myData, bytesRead); //ptr +1 changed
1114
1115        if (sMC->otherDataPresent)
1116        {
1117            ;   /* dont' care at this point, no MUX other than aac supported */
1118        }
1119
1120    }
1121    else
1122    {
1123        /*
1124         *  We have an AudioMuxElement() spread accross more than one rtp packet
1125         */
1126        if ((m_bit && framesize != pktsize + (bytesRead - 1) && !sMC->otherDataPresent) /* last block */ ||
1127                (!m_bit && framesize <  pktsize + (bytesRead - 1) && !sMC->otherDataPresent) /* intermediate block */)
1128        {
1129
1130            // to update number of bytes copied
1131            memFragOut.getMemFrag().len = 0;
1132            mediaDataOut->setMediaFragFilledLen(0, 0);
1133
1134            return FRAME_ERROR;
1135        }
1136
1137        /*
1138         *  Accumulate  blocks until the full frame is complete
1139         */
1140        oscl_memcpy((uint8*)memFragOut.getMemFrag().ptr + bytesRead, myData, pktsize);
1141        bytesRead += pktsize;
1142    }
1143
1144
1145    // to update number of bytes copied
1146    memFragOut.getMemFrag().len = bytesRead;
1147    mediaDataOut->setMediaFragFilledLen(0, bytesRead);
1148    mediaDataOut->setSeqNum(aSeqNum);
1149    mediaDataOut->setTimestamp(aTimestamp);
1150
1151
1152    firstBlock = false;     /* we already processed the first block, so this should be false  */
1153
1154    if (m_bit)              /* check if it is a complete packet (m bit ==1) */
1155    {
1156        firstBlock = true;  /* if m-bit is "1", then the farme fits in a block or this was the last
1157                               block of the frame, set for next call */
1158        framesize = 0;
1159        frameNum = 0;
1160        bytesRead = 0;
1161        compositenumframes = 0;
1162    }
1163    else
1164    {
1165        /*
1166         *  We have an AudioMuxElement() spread accross more than one rtp packet
1167         */
1168        compositenumframes++;
1169
1170        if (compositenumframes < MAX_NUM_COMPOSITE_FRAMES)
1171        {
1172            // this is not yet a finished packet
1173            return FRAME_INCOMPLETE;
1174        }
1175        else
1176        {
1177            return FRAME_ERROR;
1178        }
1179
1180    }
1181    return FRAME_COMPLETE;
1182}
1183
1184
1185
1186uint8 PV_LATM_Parser::composeMultipleFrame(uint8* aData, uint32 aDataLen, uint32 aTimestamp, uint32 aSeqNum, uint32 aMbit)
1187{
1188
1189    uint32 tmp;
1190    uint8 * myData;
1191    uint32 i;
1192
1193    int32 pktsize = aDataLen;
1194    // pool made for output data
1195    OsclRefCounterMemFrag memFragOut;
1196    mediaDataOut->getMediaFragment(0, memFragOut);
1197    // make sure we have enough memory to hold the data
1198    if (bytesRead + pktsize > currSize)
1199    {
1200        uint8 * tempPtr = (uint8*) oscl_calloc(bytesRead + pktsize, sizeof(uint8));
1201        if (tempPtr == NULL)
1202        {
1203            // memory problem?
1204            return FRAME_ERROR;
1205        }
1206        currSize = bytesRead + pktsize;
1207        oscl_memcpy(tempPtr, multiFrameBuf, bytesRead);
1208        oscl_free(multiFrameBuf);
1209        multiFrameBuf = tempPtr;
1210    }
1211
1212    oscl_memcpy(multiFrameBuf + bytesRead, aData, pktsize);
1213
1214    bytesRead += pktsize;
1215    //newpkt->frame_size = bytesRead;
1216
1217    // to update number of bytes copied
1218    memFragOut.getMemFrag().len = bytesRead;
1219    mediaDataOut->setMediaFragFilledLen(0, bytesRead);
1220    mediaDataOut->setSeqNum(aSeqNum);
1221    mediaDataOut->setTimestamp(aTimestamp);
1222
1223    if (aMbit)
1224    {
1225        // means this is the last packet for this audioMuxElement
1226
1227        myData = multiFrameBuf;
1228
1229        uint32 outPtrPos = 0;
1230        for (i = 0; i <= sMC->numSubFrames; i++)
1231        {
1232            framesize = 0;
1233            do
1234            {
1235                tmp = *(myData);
1236                framesize += tmp;
1237            }
1238            while (*(myData++) == 0xff);
1239
1240            //int32 bUsed = (framesize/255)+1; // 0-254: 1, 255-511: 2 ...
1241            // do a check on the last one
1242            if (i == sMC->numSubFrames && !sMC->otherDataPresent)
1243            {
1244                if (framesize != bytesRead - (myData - multiFrameBuf))
1245                {
1246                    // to update number of bytes copied
1247                    memFragOut.getMemFrag().len = 0;
1248                    mediaDataOut->setMediaFragFilledLen(0, 0);
1249
1250                    return FRAME_INCOMPLETE;
1251                }
1252            }
1253            oscl_memcpy((uint8*)memFragOut.getMemFrag().ptr + outPtrPos, myData, framesize);
1254            myData += framesize;
1255            outPtrPos += framesize;
1256        }
1257
1258
1259
1260        // to update number of bytes copied
1261        memFragOut.getMemFrag().len = outPtrPos;
1262        mediaDataOut->setMediaFragFilledLen(0, outPtrPos);
1263
1264        bytesRead = 0;
1265        framesize = 0;
1266        compositenumframes = 0;
1267
1268    }
1269    else
1270    {
1271        compositenumframes++;
1272
1273        if (compositenumframes < MAX_NUM_COMPOSITE_FRAMES)
1274        {
1275            return FRAME_INCOMPLETE;
1276        }
1277        else
1278        {
1279            return FRAME_ERROR;
1280        }
1281
1282    }
1283
1284    return FRAME_COMPLETE;
1285}
1286
1287uint32 BufferShowBits(uint8 *inbuf, uint32 pos1, uint32 pos2)
1288{
1289    uint32 ptr1 = pos1 % 8, ptr2 = pos2 % 8, Ptr1 = pos1 >> 3, Ptr2 = pos2 >> 3;
1290    uint32 tmpvar = 0;
1291    // this really should be static, but not supported in EPOC
1292    uint8 mask[] = {255, 127, 63, 31, 15, 7, 3, 1, 0};
1293
1294    if (Ptr1 == Ptr2) // When all the bits to copy are in the same byte
1295    {
1296        return ((inbuf[Ptr1] & (mask[ptr1] - mask[ptr2+1])) >> (7 - ptr2));
1297    }
1298    else // Otherwise
1299    {
1300        tmpvar = inbuf[Ptr1] & mask[ptr1];
1301        for (Ptr1 ++; Ptr1 < Ptr2; Ptr1 ++)
1302        {
1303            tmpvar <<= 8;
1304            tmpvar += inbuf[Ptr1];
1305        }
1306        tmpvar <<= (ptr2 + 1);
1307        tmpvar += (inbuf[Ptr2] & (255 - mask[ptr2+1])) >> (7 - ptr2);
1308    }
1309    return tmpvar;
1310}
1311
1312uint32 BufferReadBits(uint8 *inbuf, uint32 *pos1, int32 len)
1313{
1314    uint32 rval = BufferShowBits(inbuf, *pos1, (*pos1) + len - 1);
1315    *pos1 += len;
1316    return rval;
1317}
1318
1319