Home | History | Annotate | Download | only in src
      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 ///////////////////////////////////////////////////////////////////////////////
     19 //
     20 // RFC3640_payload_parser.cpp
     21 //
     22 // Implementation of payload parser for RFC3640 RTP format.
     23 //
     24 ///////////////////////////////////////////////////////////////////////////////
     25 
     26 #include "oscl_mem.h"
     27 #include "rfc3640_payload_parser.h"
     28 #include "bitstreamparser.h"
     29 #include "oscl_byte_order.h"
     30 #include "rfc3640_media_info.h"
     31 
     32 //Until the fileformat node and decoder are re-worked to handle multiple-fragments
     33 //per media message, we'll need to use this switch to control the output of the
     34 //payload parser
     35 #define RFC3640_ONE_FRAGMENT_PER_MEDIA_MSG 1
     36 
     37 //Default Values
     38 #define AAC_HBR_SIZELENGTH_DEFAULT_VALUE        13
     39 #define AAC_HBR_INDEXLENGTH_DEFAULT_VALUE       3
     40 #define AAC_HBR_INDEXDELTALENGTH_DEFAULT_VALUE  3
     41 #define AAC_HBR_CTSDELTALENGTH_DEFAULT_VALUE    0
     42 #define AAC_HBR_DTSDELTALENGTH_DEFAULT_VALUE    0
     43 #define AAC_HBR_HEADERSLENGTH_DEFAULT_VALUE     16
     44 #define AAC_HBR_AUXDATASIZELENGTH_DEFAULT_VALUE 0
     45 
     46 ///////////////////////////////////////////////////////////////////////////////
     47 //
     48 // Constructor/Destructor
     49 //
     50 ///////////////////////////////////////////////////////////////////////////////
     51 
     52 OSCL_EXPORT_REF RFC3640PayloadParser::RFC3640PayloadParser()
     53 {
     54     //Default to no headers at all.
     55     //This is just in case Init() is never called.
     56     headersPresent = false;
     57     headersLength = 0;
     58     sizeLength = 0;
     59     indexLength = 0;
     60     indexDeltaLength = 0;
     61     CTSDeltaLength = 0;
     62     DTSDeltaLength = 0;
     63     randomAccessIndication = false;
     64     auxDataSizeLength = 0;
     65 }
     66 
     67 OSCL_EXPORT_REF RFC3640PayloadParser::~RFC3640PayloadParser()
     68 {
     69 }
     70 
     71 ///////////////////////////////////////////////////////////////////////////////
     72 //
     73 // Initialization
     74 //
     75 ///////////////////////////////////////////////////////////////////////////////
     76 
     77 OSCL_EXPORT_REF bool RFC3640PayloadParser::Init(mediaInfo* config)
     78 {
     79     Oscl_Vector<PayloadSpecificInfoTypeBase*, OsclMemAllocator> payloadInfo;
     80     payloadInfo = config->getPayloadSpecificInfoVector();
     81     PayloadSpecificInfoTypeBase* payloadInfoBase = payloadInfo[0]; // is this "0" assumption okay???
     82     RFC3640PayloadSpecificInfoType* r3640PayloadInfo =
     83         OSCL_STATIC_CAST(RFC3640PayloadSpecificInfoType*, payloadInfoBase);
     84     rfc3640_mediaInfo *r3640m = OSCL_STATIC_CAST(rfc3640_mediaInfo *, config);
     85     bool retVal = false;
     86 
     87     //TODO: Implement other modes (such as CELP-cbr, CELP-vbr, AAC-lbr, etc...).
     88     sizeLength             = r3640PayloadInfo->getSizeLength();
     89     indexLength            = r3640PayloadInfo->getIndexLength();
     90     indexDeltaLength       = r3640PayloadInfo->getIndexDeltaLength();
     91     CTSDeltaLength         = r3640PayloadInfo->getCTSDeltaLength();
     92     DTSDeltaLength         = r3640PayloadInfo->getDTSDeltaLength();
     93     randomAccessIndication = false;
     94 
     95     //We support AAC-hbr mode only.
     96     if (!oscl_strncmp(r3640m->getMode(), "AAC-hbr", oscl_strlen("AAC-hbr")))
     97     {
     98         headersPresent         = true;
     99         headersLength          = AAC_HBR_HEADERSLENGTH_DEFAULT_VALUE;
    100         auxDataSizeLength      = AAC_HBR_AUXDATASIZELENGTH_DEFAULT_VALUE;
    101 
    102         //do sanity check on values. Only supporting AAC_HBR default fixed values.
    103         if ((sizeLength != AAC_HBR_SIZELENGTH_DEFAULT_VALUE) ||
    104                 (indexLength != AAC_HBR_INDEXLENGTH_DEFAULT_VALUE) ||
    105                 (indexDeltaLength != AAC_HBR_INDEXDELTALENGTH_DEFAULT_VALUE))
    106         {
    107             retVal = true;
    108         }
    109 
    110     }
    111     else
    112     {
    113         retVal = true;
    114     }
    115 
    116 
    117     return retVal;
    118 }
    119 
    120 ///////////////////////////////////////////////////////////////////////////////
    121 //
    122 // Payload parsing
    123 //
    124 ///////////////////////////////////////////////////////////////////////////////
    125 
    126 OSCL_EXPORT_REF PayloadParserStatus
    127 RFC3640PayloadParser::Parse(const Payload& inputPacket,
    128                             Oscl_Vector<Payload, OsclMemAllocator>& vParsedPayloads)
    129 {
    130     // Many of OsclRefCounterMemFrag's member functions
    131     //should be const functions so this casting away constness is not necessary.
    132     Payload& input = const_cast<Payload&>(inputPacket);
    133 
    134     //@TODO: Implement AU de-interleaving
    135 
    136     Payload out;
    137 
    138     out.stream       = inputPacket.stream;
    139     out.marker       = inputPacket.marker;
    140     out.randAccessPt = inputPacket.randAccessPt;
    141     out.sequence     = inputPacket.sequence + 1;
    142     out.timestamp    = inputPacket.timestamp;
    143     //Creating a boolean for checking whether RFC3640_ONE_FRAGMENT_PER_MEDIA_MSG is defined or not
    144     bool rfc3640_one_fragement_per_media     = false;
    145 
    146 #ifndef RFC3640_ONE_FRAGMENT_PER_MEDIA_MSG
    147     rfc3640_one_fragement_per_media = true;
    148 #endif
    149 
    150     // Many functions calls inside this for loop may Leave because of an
    151     // overflow.
    152     int32 err;
    153     OSCL_TRY(err,
    154              //Loop through all of the packets.
    155              for (uint32 fragmentNumber = 0; fragmentNumber < inputPacket.vfragments.size(); fragmentNumber++)
    156 {
    157     //
    158     // Strip RFC 3640 header section and auxiliary section.
    159     //
    160 
    161     //Establish a pointer to the payload fragment for iterating past the
    162     //header and aux section.
    163     BitStreamParser fragment((uint8*)input.vfragments[fragmentNumber].getMemFragPtr(),
    164                              input.vfragments[fragmentNumber].getMemFragSize());
    165 
    166         //In some cases, such as with fixed-length AUs, the header is not present.
    167         //Only process the header if it is present.
    168         uint16 headersLength = 0;
    169         if (headersPresent)
    170         {
    171             //Read the header length from the first 2 octets.
    172             //Include the size of this headersLength field in the total length.
    173             headersLength = fragment.ReadUInt16() + BITS_PER_UINT16;
    174         }
    175 
    176         uint8  accessUnits  = 0; //controls index field interpretation (index or delta)
    177         uint32 size         = 0; //size of the AU
    178         uint32 index        = 0; //used for interleaving
    179         uint32 indexDelta   = 0; //used for interleaving
    180         int    CTSFlag      = 0; //composition time stamp
    181         uint32 CTSDelta     = 0; //composition time stamp
    182         int    DTSFlag      = 0; //decoding time stamp
    183         uint32 DTSDelta     = 0; //decoding time stamp
    184         int    RAPFlag      = 0; //random access point - used to mark a key frame
    185         uint32 auxDataSize  = 0;
    186 
    187         //Loop through all of the access units in the packet.
    188         while (fragment.BitsRead() < headersLength)
    189         {
    190             //If the header is present, parse it.
    191             if (headersLength)
    192             {
    193                 if (0 != sizeLength)
    194                 {
    195                     //Read the AU Size field.
    196                     size = fragment.ReadBits(sizeLength);
    197                 }
    198 
    199                 //If the index field is present...
    200                 if (0 != indexLength)
    201                 {
    202                     //If this is the first access unit header...
    203                     if (0 == accessUnits)
    204                     {
    205                         //The AU index only occurs in the first header.
    206                         index = fragment.ReadBits(indexLength);
    207                     }
    208                     else
    209                     {
    210                         indexDelta = fragment.ReadBits(indexDeltaLength);
    211                     }
    212                 }
    213 
    214                 //From RFC3640: "The CTS-flag field MUST be present in each AU-header
    215                 //               if the length of the CTS-delta field is signaled to
    216                 //               be larger than zero."
    217                 if (0 != CTSDeltaLength)
    218                 {
    219                     CTSFlag = fragment.ReadBits(1);
    220                     if (CTSFlag)
    221                     {
    222                         CTSDelta = fragment.ReadBits(CTSDeltaLength);
    223                     }
    224                 }
    225 
    226                 if (0 != DTSDeltaLength)
    227                 {
    228                     DTSFlag = fragment.ReadBits(1);
    229                     if (DTSFlag)
    230                     {
    231                         DTSDelta = fragment.ReadBits(DTSDeltaLength);
    232                     }
    233                 }
    234 
    235                 if (randomAccessIndication)
    236                 {
    237                     RAPFlag = fragment.ReadBits(1);
    238                 }
    239             }
    240 
    241 
    242             if (rfc3640_one_fragement_per_media == true)
    243             {
    244                 // At this time the decoder cannot handle multiple fragments.
    245 
    246                 OsclMemoryFragment memfrag;
    247                 //memfrag.ptr = NULL; //Unknown at this time.
    248                 memfrag.len = size;
    249                 input.vfragments[fragmentNumber].getRefCounter()->addRef();
    250                 OsclRefCounterMemFrag refCntMemFrag(memfrag,
    251                                                     input.vfragments[fragmentNumber].getRefCounter(),
    252                                                     memfrag.len);
    253                 out.vfragments.push_back(refCntMemFrag);
    254             }
    255             else
    256             {
    257                 // Instead of creating multiple fragments, point to the first fragment, but
    258                 // increment the size field to span all access units. The decoder is still
    259                 // getting multiple frames in memory, but the data structure makes it appear as just one.
    260                 // This only works for non-interleaved access units & can only be a temporary solution
    261                 if (accessUnits == 0)
    262                 {
    263                     OsclMemoryFragment memfrag;
    264                     memfrag.ptr = (uint8*)(input.vfragments[fragmentNumber].getMemFragPtr()) + (headersLength / 8);
    265                     memfrag.len = input.vfragments[fragmentNumber].getMemFragSize() - (headersLength / 8);
    266                     input.vfragments[fragmentNumber].getRefCounter()->addRef();
    267                     OsclRefCounterMemFrag refCntMemFrag(memfrag,
    268                                                         input.vfragments[fragmentNumber].getRefCounter(),
    269                                                         memfrag.len);
    270                     out.vfragments.push_back(refCntMemFrag);
    271                 }
    272             }
    273 
    274             accessUnits++;
    275         }
    276 
    277         //Processed the header.  Skip past any padding.
    278         if (fragment.GetBitPos() != MOST_SIG_BIT)
    279         {
    280             fragment.NextBits(fragment.GetBitPos() + 1);
    281         }
    282 
    283         //Now skip over the aux data region.
    284         if (auxDataSizeLength)
    285         {
    286             auxDataSize = fragment.ReadBits(auxDataSizeLength);
    287             if (auxDataSize)
    288             {
    289                 //Skip over the aux data region.
    290                 fragment.NextBits(auxDataSize);
    291                 //Skip past any padding.
    292                 if (fragment.GetBitPos() != MOST_SIG_BIT)
    293                 {
    294                     fragment.NextBits(fragment.GetBitPos() + 1);
    295                 }
    296             }
    297         }
    298 
    299         if (rfc3640_one_fragement_per_media == true)
    300         {
    301             //Update the fragment pointers with real values now that we have
    302             //parsed the headers.
    303             //The output vector may contain fragments from previous runs, so
    304             //start with the last fragments that we pushed on the back of the vector.
    305             for (uint32 i = (out.vfragments.size() - accessUnits); i < out.vfragments.size(); i++)
    306             {
    307                 out.vfragments[i].getMemFrag().ptr = fragment.GetBytePos();
    308                 fragment.NextBits(out.vfragments[i].getMemFrag().len * BITS_PER_BYTE);
    309             }
    310         }
    311 
    312     }
    313             ); // End of OSCL_TRY
    314 
    315     if (err != OsclErrNone)
    316     {
    317         return PayloadParserStatus_Failure;
    318     }
    319     vParsedPayloads.push_back(out);
    320 
    321     return PayloadParserStatus_Success;
    322 }
    323 
    324 ///////////////////////////////////////////////////////////////////////////////
    325 //
    326 // Repositioning related
    327 //
    328 ///////////////////////////////////////////////////////////////////////////////
    329 
    330 OSCL_EXPORT_REF void RFC3640PayloadParser::Reposition(const bool adjustSequence, const uint32 stream, const uint32 seqnum)
    331 {
    332     OSCL_UNUSED_ARG(adjustSequence);
    333     OSCL_UNUSED_ARG(stream);
    334     OSCL_UNUSED_ARG(seqnum);
    335 }
    336 
    337 OSCL_EXPORT_REF uint32 RFC3640PayloadParser::GetMinCurrTimestamp()
    338 {
    339     return 0;
    340 }
    341