• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RFC3640PayloadParser()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 
~RFC3640PayloadParser()67 OSCL_EXPORT_REF RFC3640PayloadParser::~RFC3640PayloadParser()
68 {
69 }
70 
71 ///////////////////////////////////////////////////////////////////////////////
72 //
73 // Initialization
74 //
75 ///////////////////////////////////////////////////////////////////////////////
76 
Init(mediaInfo * config)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
Parse(const Payload & inputPacket,Oscl_Vector<Payload,OsclMemAllocator> & vParsedPayloads)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 
Reposition(const bool adjustSequence,const uint32 stream,const uint32 seqnum)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 
GetMinCurrTimestamp()337 OSCL_EXPORT_REF uint32 RFC3640PayloadParser::GetMinCurrTimestamp()
338 {
339     return 0;
340 }
341