|
1 /* |
|
2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: AVC De-Payloadization class |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 // ============================ INCLUDES ======================================= |
|
22 |
|
23 #include"rfc3984decode.h" |
|
24 |
|
25 // ============================ MEMBER FUNCTIONS =============================== |
|
26 _LIT8(AVCPSC1, "\x0\x0\x0\x1"); |
|
27 |
|
28 // ----------------------------------------------------------------------------- |
|
29 // CRFC3984Decode::CRFC3984Decode() |
|
30 // Default Constructor |
|
31 // (other items were commented in a header). |
|
32 // ----------------------------------------------------------------------------- |
|
33 // |
|
34 CRFC3984Decode::CRFC3984Decode() |
|
35 { |
|
36 iNalCount = 0; |
|
37 iVirtualDON = 0; |
|
38 |
|
39 } |
|
40 |
|
41 // ----------------------------------------------------------------------------- |
|
42 // CRFC3984Decode::~CRFC3984Decode() |
|
43 // Default Destructor |
|
44 // (other items were commented in a header). |
|
45 // ----------------------------------------------------------------------------- |
|
46 // |
|
47 CRFC3984Decode::~CRFC3984Decode() |
|
48 { |
|
49 // TODO :: cleanup iBuffer in this destructor |
|
50 } |
|
51 |
|
52 // ----------------------------------------------------------------------------- |
|
53 // CRFC3984Decode::NewL() |
|
54 // First stage constructor |
|
55 // (other items were commented in a header). |
|
56 // ----------------------------------------------------------------------------- |
|
57 // |
|
58 |
|
59 CRFC3984Decode * CRFC3984Decode::NewL() |
|
60 { |
|
61 CRFC3984Decode * self = new(ELeave) CRFC3984Decode; |
|
62 CleanupStack::PushL( self ); |
|
63 self->ConstructL( ); |
|
64 CleanupStack::Pop(); |
|
65 return self; |
|
66 } |
|
67 |
|
68 // ----------------------------------------------------------------------------- |
|
69 // CRFC3984Decode::ConstructL() |
|
70 // Initializing common members |
|
71 // ----------------------------------------------------------------------------- |
|
72 // |
|
73 |
|
74 void CRFC3984Decode::ConstructL() |
|
75 { |
|
76 iNalCount = 0; |
|
77 iVirtualDON = 0; |
|
78 } |
|
79 |
|
80 // ----------------------------------------------------------------------------- |
|
81 // CRFC3984Decode::DePayloadizeFrame() |
|
82 // Purpose : This function receives the encoded frame and payloadizes it based on the packetization_mode value |
|
83 // Parameters : aBuffer - Buffer containing the received NAL unit |
|
84 // aTimeStamp - Timestamp to go into RTP |
|
85 // aMarkerBit - Marker Bit indication (this function sets it for key frames) |
|
86 // aNalCount - Returns the NAL count through this reference |
|
87 // Return Value: ETrue if correct parsing done, EFalse if an error occured |
|
88 // ----------------------------------------------------------------------------- |
|
89 // |
|
90 |
|
91 TBool CRFC3984Decode::DePayloadizeFrameL(TDes8 & aBuffer, TUint aTimeStamp, TUint aArrivalTime, TUint16 aSeqNo, TUint8 & aMarkerBit, TInt & aNalCount) |
|
92 { |
|
93 |
|
94 TInt index = 0; |
|
95 CAvcRtpStruct * pRtpStruct = NULL; |
|
96 HBufC8 * pBuffer = NULL; |
|
97 TInt16 lowerSeqNo = aSeqNo; |
|
98 |
|
99 |
|
100 TUint8 header = aBuffer[index]; |
|
101 TUint8 type = header & 0x1f; |
|
102 |
|
103 if(type <= PACKET_NAL_UNIT){ // SNALU packet -- add as they are |
|
104 // storing reference as it is |
|
105 pRtpStruct = new (ELeave) CAvcRtpStruct; // allocating memory to store RTP header information and data pointer |
|
106 pRtpStruct->iMarkerBit = aMarkerBit; |
|
107 pRtpStruct->iArrivalTime = aArrivalTime; |
|
108 pRtpStruct->iTimeStamp = aTimeStamp; |
|
109 pRtpStruct->iSeqNo = aSeqNo; |
|
110 pRtpStruct->iPacketType = type; |
|
111 pRtpStruct->iDon = (iVirtualDON++)%65535; // Since 1 NAL/slice, no need for virtual DON and keeping it constant. |
|
112 |
|
113 CleanupStack::PushL( pRtpStruct ); // pushing to stack for leave operation |
|
114 //pDes = new (ELeave) TBuf8<aBuffer.Size()); // allocating memory for data |
|
115 pBuffer = HBufC8::New(aBuffer.Size()); |
|
116 if(!pBuffer) |
|
117 { |
|
118 User::Leave(KErrNoMemory); |
|
119 } |
|
120 CleanupStack::Pop(); |
|
121 TPtr8 pDes = pBuffer->Des( ); |
|
122 pDes.Copy(aBuffer); // copying data |
|
123 pRtpStruct->iDes = pBuffer; |
|
124 pBuffer = NULL; |
|
125 iBuffers.Insert(pRtpStruct, iNalCount); // storing pointer into the pointer array for retreival later on |
|
126 iNalCount += 1; // incrementing total NAL count by 1 |
|
127 } |
|
128 else if(type == PACKET_STAP_A){ // STAP-A packet -- seperate and add using a virtual don number |
|
129 TUint accumSize = 0; |
|
130 TUint16 nalSize = 0; |
|
131 |
|
132 accumSize += 1; // incrementing to point ahead of header |
|
133 while(accumSize != aBuffer.Size()){ |
|
134 nalSize = Read16(aBuffer, accumSize); |
|
135 accumSize += 2; |
|
136 if(nalSize > 0 && nalSize <= aBuffer.Size()){ // valid size, copy data |
|
137 // storing reference as it is |
|
138 pRtpStruct = new (ELeave) CAvcRtpStruct; // allocating memory to store RTP header information and data pointer |
|
139 pRtpStruct->iMarkerBit = aMarkerBit; |
|
140 pRtpStruct->iArrivalTime = aArrivalTime; |
|
141 pRtpStruct->iTimeStamp = aTimeStamp; |
|
142 pRtpStruct->iSeqNo = aSeqNo; |
|
143 pRtpStruct->iPacketType = type; |
|
144 pRtpStruct->iDon = (iVirtualDON++)%65535; // virtual DON, wrapping around at 65K (it spans over many NAL units) |
|
145 |
|
146 CleanupStack::PushL( pRtpStruct ); // pushing to stack for leave operation |
|
147 // pDes = new (ELeave) TBuf8<aBuffer.Size()); // allocating memory for data |
|
148 //pBuffer = HBufC8::New(aBuffer.Size()); |
|
149 pBuffer = HBufC8::New(nalSize); |
|
150 if(!pBuffer) |
|
151 { |
|
152 User::Leave(KErrNoMemory); |
|
153 } |
|
154 CleanupStack::Pop(); |
|
155 TPtr8 pDes1 = pBuffer->Des( ); |
|
156 TPtr8 pStart = aBuffer.MidTPtr(accumSize); |
|
157 pDes1.Copy(pStart.Ptr(), nalSize); // copying data |
|
158 pRtpStruct->iDes = pBuffer; |
|
159 pBuffer = NULL; |
|
160 iBuffers.Insert(pRtpStruct, iNalCount); // storing pointer into the pointer array for retreival later on |
|
161 iNalCount += 1; // incrementing total NAL count by 1 |
|
162 |
|
163 accumSize += nalSize; |
|
164 |
|
165 } |
|
166 } |
|
167 } |
|
168 else if(type == PACKET_FU_A){ // FU-A packet -- add as they are, the jitter buffer removal side will assemble them |
|
169 // storing reference as it is, since FU-A and FU-B will be depacketized at removal time from the jitter buffer |
|
170 // however, for FU-B extract the DON number |
|
171 |
|
172 // reading from FU-header byte the start bit |
|
173 index++; // going to FU-Header Byte start bit, end bit and R bit |
|
174 TUint8 startBit = 0; |
|
175 const TUint8 * FUHeader = NULL; |
|
176 TUint8 FUHeader1 = 0; |
|
177 TInt bufSize = aBuffer.Size(); |
|
178 startBit = aBuffer[index]; |
|
179 startBit &= 0x80; // keeping just the start bit |
|
180 startBit = startBit >> 7; |
|
181 if(startBit == 1) |
|
182 { |
|
183 pBuffer = HBufC8::New(aBuffer.Size( )+3); // excluding FU NAL Header byte and adding size of AVCPSC1 |
|
184 if(!pBuffer) |
|
185 { |
|
186 User::Leave(KErrNoMemory); |
|
187 } |
|
188 |
|
189 TPtr8 pDesBuf = pBuffer->Des(); |
|
190 TPtr8 headerPtr = aBuffer.MidTPtr(index); |
|
191 FUHeader = headerPtr.Ptr(); |
|
192 FUHeader1 = *FUHeader; |
|
193 header &= 0xE0; // making lower bits 0 i.e. type field |
|
194 header |= (*FUHeader & 0x1F); // now header has the actual NAL unit header values. |
|
195 pDesBuf.Append(AVCPSC1); // appending start code |
|
196 pDesBuf.Append(&header, 1); // appending reconstructed header |
|
197 TPtr8 startPtr = aBuffer.MidTPtr(index+1); // getting pointer to start of NAL unit |
|
198 pDesBuf.Append(startPtr.Ptr(), bufSize-2); // copying NAL data |
|
199 } |
|
200 else |
|
201 { |
|
202 |
|
203 pBuffer = HBufC8::New(aBuffer.Size( )-1); // excluding FU NAL Header byte |
|
204 if(!pBuffer) |
|
205 { |
|
206 User::Leave(KErrNoMemory); |
|
207 } |
|
208 |
|
209 TPtr8 pDesBuf = pBuffer->Des(); |
|
210 TPtr8 startPtr = aBuffer.MidTPtr(index); // pointing to FUHeader byte |
|
211 FUHeader = startPtr.Ptr(); |
|
212 FUHeader1 = *FUHeader; |
|
213 startPtr = aBuffer.MidTPtr(index+1); // pointing to start of actual data |
|
214 pDesBuf.Append(startPtr.Ptr( ), bufSize-2); // copying FU-Header and data |
|
215 } |
|
216 |
|
217 pRtpStruct = new (ELeave) CAvcRtpStruct; // allocating memory to store RTP header information and data pointer |
|
218 pRtpStruct->iMarkerBit = aMarkerBit; |
|
219 pRtpStruct->iArrivalTime = aArrivalTime; |
|
220 pRtpStruct->iTimeStamp = aTimeStamp; |
|
221 pRtpStruct->iSeqNo = aSeqNo; |
|
222 pRtpStruct->iPacketType = type; |
|
223 pRtpStruct->iDon = (iVirtualDON++)%65535; // keeping virtual DON for FU-A as zero too |
|
224 pRtpStruct->iDes = pBuffer; |
|
225 pRtpStruct->iFUHeader = FUHeader1; // index currently pointing to FU-Header Byte |
|
226 pBuffer = NULL; |
|
227 iBuffers.Insert(pRtpStruct, iNalCount); // storing pointer into the pointer array for retreival later on |
|
228 iNalCount += 1; |
|
229 } |
|
230 |
|
231 aNalCount = iNalCount; |
|
232 return ETrue; |
|
233 } |
|
234 |
|
235 // ----------------------------------------------------------------------------- |
|
236 // CRFC3984Decode::Write16() |
|
237 // Purpose : This function writes the 16 bit value in network byte order in buffer aDes (appends it to the next location) |
|
238 // Parameters : aDes - Buffer to which value has to be written |
|
239 // aValue - Value to be written |
|
240 // Return Value: |
|
241 // ----------------------------------------------------------------------------- |
|
242 // |
|
243 |
|
244 void CRFC3984Decode::Write16(TDes8 & aDes, TUint16 aValue) |
|
245 { |
|
246 TUint8 firstByte = (aValue & 0xFF00) >> 8; |
|
247 TUint8 secondByte = (aValue & 0xFF); |
|
248 aDes.Append(&firstByte, 1); |
|
249 aDes.Append(&secondByte, 1); |
|
250 |
|
251 } |
|
252 |
|
253 // ----------------------------------------------------------------------------- |
|
254 // CRFC3984Decode::Read16() |
|
255 // Purpose : This function reads the 16 bit value in network byte order in buffer aDes (appends it to the next location) |
|
256 // Parameters : aDes - Buffer to read from |
|
257 // aIndex - Buffer index where to read from |
|
258 // Return Value: Returns the 16-bit value |
|
259 // ----------------------------------------------------------------------------- |
|
260 // |
|
261 |
|
262 TUint16 CRFC3984Decode::Read16(TDes8 & aDes, TInt aIndex) |
|
263 { |
|
264 TUint16 value; |
|
265 |
|
266 value = (aDes[aIndex+1]) + (aDes[aIndex] << 8); |
|
267 |
|
268 return value; |
|
269 } |
|
270 |
|
271 // ----------------------------------------------------------------------------- |
|
272 // CRFC3984Decode::GetNalUnit(TInt aIndex) |
|
273 // Purpose : This function returns the depayloadized NAL unit with RTP header information |
|
274 // Parameters : aIndex - Index of the entry |
|
275 // |
|
276 // Return Value: Returns a pointer to the CAvcRtpStruct structure. |
|
277 // ----------------------------------------------------------------------------- |
|
278 // |
|
279 |
|
280 CAvcRtpStruct * CRFC3984Decode::GetNalUnit(TInt aIndex) |
|
281 { |
|
282 CAvcRtpStruct * ptr; |
|
283 if(aIndex >= iNalCount) |
|
284 return 0; |
|
285 |
|
286 ptr = iBuffers[aIndex]; |
|
287 return ptr; |
|
288 } |
|
289 |
|
290 |
|
291 void CRFC3984Decode::ClearBuffer() |
|
292 { |
|
293 if(iNalCount == 0) |
|
294 return; |
|
295 |
|
296 TInt count = 0; |
|
297 CAvcRtpStruct * ptr = NULL; |
|
298 for(count = 0; count < iNalCount; count++){ |
|
299 ptr = iBuffers[count]; |
|
300 |
|
301 if(ptr->iDes) delete ptr->iDes; |
|
302 if(ptr) delete ptr; |
|
303 ptr = NULL; |
|
304 |
|
305 } |
|
306 iBuffers.Reset( ); |
|
307 iNalCount = 0; |
|
308 } |
|
309 |
|
310 |
|
311 // EOF |