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 "tscsrpbuffer.h"
19 #define MAX_TSCSRP_BUFFER_SZ 768
20 #define NUM_TSCSRP_FRAGS 24
21 #define PV_TSC_SRP_BUFFER_TIMER_ID 1
22 #define TSC_SRP_BUFFER_TIMEOUT 50
23
24
NewL(TscSrpBuffer * aTscSrpBuffer)25 TscSrpBufferLLPortIn *TscSrpBufferLLPortIn::NewL(TscSrpBuffer *aTscSrpBuffer)
26 {
27 TscSrpBufferLLPortIn *self = OSCL_NEW(TscSrpBufferLLPortIn, (aTscSrpBuffer));
28 if (self)
29 {
30 ConstructSelf(self);
31 }
32 else
33 {
34 OSCL_LEAVE(PVMFErrNoMemory);
35 }
36 return self;
37 }
38
ConstructSelf(TscSrpBufferLLPortIn * self)39 void TscSrpBufferLLPortIn::ConstructSelf(TscSrpBufferLLPortIn* self)
40 {
41 int error;
42 OSCL_TRY(error, self->ConstructL(););
43 if (error)
44 {
45 OSCL_DELETE(self);
46 OSCL_LEAVE(error);
47 }
48 }
49
50
~TscSrpBufferLLPortIn()51 TscSrpBufferLLPortIn::~TscSrpBufferLLPortIn()
52 {
53 if (iFrag)
54 {
55 iMediaFragAlloc->deallocate_fragment(iFrag);
56 iFrag = NULL;
57 }
58
59 if (iPkt)
60 {
61 iPkt->Clear();
62 iMediaPktAlloc.deallocate_packet(iPkt);
63 iPkt = NULL;
64 }
65
66 if (iMediaFragAlloc)
67 {
68 OSCL_DELETE(iMediaFragAlloc);
69 iMediaFragAlloc = NULL;
70 }
71 }
72
Receive(PVMFSharedMediaMsgPtr aMsg)73 PVMFStatus TscSrpBufferLLPortIn::Receive(PVMFSharedMediaMsgPtr aMsg)
74 {
75 OsclRefCounterMemFrag frag;
76 PVMFSharedMediaDataPtr mediaData;
77 convertToPVMFMediaData(mediaData, aMsg);
78 uint32 fullH245Msg = mediaData->getMarkerInfo();
79
80 if (iFrag == NULL)
81 {
82 iFrag = iMediaFragAlloc->allocate_fragment(MAX_TSCSRP_BUFFER_SZ);
83 if (iFrag == NULL) return PVMFFailure;
84 }
85
86 for (uint32 i = 0; i < mediaData->getNumFragments(); i++)
87 {
88 if (mediaData->getMediaFragment(i, frag))
89 {
90 if ((frag.getMemFragSize() + iCurSize) > MAX_TSCSRP_BUFFER_SZ)
91 {
92 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iTscSrpBuffer->iLogger, PVLOGMSG_STACK_TRACE,
93 (0, "TscSrpBufferLLPortIn::PutData MAX_TSCSRP_BUFFER_SZ size exceeded"));
94 fullH245Msg = true;
95 break;
96 }
97 else
98 {
99 oscl_memcpy(iFrag->GetPtr() + iCurSize, frag.getMemFragPtr(),
100 frag.getMemFragSize());
101 iCurSize += frag.getMemFragSize();
102 }
103 }
104 }
105
106 if (fullH245Msg)
107 {
108 iFrag->GetFragment()->len = iCurSize;
109 iPkt->AddMediaFragment(iFrag);
110 iMediaFragAlloc->deallocate_fragment(iFrag);
111 iFrag = NULL;
112 iCurSize = 0;
113
114 iTscSrpBuffer->ProcessIncomingSrpPacket(iPkt);
115 iPkt->Clear();
116 }
117
118 return PVMFSuccess;
119 }
120
ConstructL()121 void TscSrpBufferLLPortIn::ConstructL()
122 {
123 iMediaFragAlloc = OSCL_NEW(PoolFragmentAllocator, (NUM_TSCSRP_FRAGS,
124 MAX_TSCSRP_BUFFER_SZ));
125 OsclError::LeaveIfNull(iMediaFragAlloc);
126 iPkt = iMediaPktAlloc.allocate_packet();
127 }
128
NewL()129 TscSrpBuffer *TscSrpBuffer::NewL()
130 {
131 TscSrpBuffer *self = OSCL_NEW(TscSrpBuffer, ());
132 if (self)
133 {
134 ConstructSelf(self);
135 }
136 else
137 {
138 OSCL_LEAVE(PVMFErrNoMemory);
139 }
140
141 return self;
142 }
143
ConstructSelf(TscSrpBuffer * self)144 void TscSrpBuffer::ConstructSelf(TscSrpBuffer* self)
145 {
146 int error;
147 OSCL_TRY(error, self->ConstructL(););
148 if (error)
149 {
150 OSCL_DELETE(self);
151 OSCL_LEAVE(error);
152 }
153 }
154
155
~TscSrpBuffer()156 TscSrpBuffer::~TscSrpBuffer()
157 {
158 iTxData.Unbind();
159
160 if (iLLPortIn)
161 {
162 OSCL_DELETE(iLLPortIn);
163 iLLPortIn = NULL;
164 }
165
166 if (iLLPortOut)
167 {
168 OSCL_DELETE(iLLPortOut);
169 iLLPortOut = NULL;
170 }
171
172 if (iTimer)
173 {
174 iTimer->Clear();
175 OSCL_DELETE(iTimer);
176 iTimer = NULL;
177 }
178
179 if (iTxPacketAlloc)
180 {
181 OSCL_DELETE(iTxPacketAlloc);
182 iTxPacketAlloc = NULL;
183 }
184
185 if (iTxMediaDataImplMemAlloc)
186 {
187 OSCL_DELETE(iTxMediaDataImplMemAlloc);
188 iTxMediaDataImplMemAlloc = NULL;
189 }
190
191 if (iTxMediaMsgPoolAlloc)
192 {
193 OSCL_DELETE(iTxMediaMsgPoolAlloc);
194 iTxMediaMsgPoolAlloc = NULL;
195 }
196 }
197
ProcessIncomingSrpPacket(MediaPacket * pPkt)198 void TscSrpBuffer::ProcessIncomingSrpPacket(MediaPacket* pPkt)
199 {
200 iH245Interface.Dispatch(pPkt);
201 }
202
ProcessOutgoingH245Packet(MediaPacket * pPkt)203 void TscSrpBuffer::ProcessOutgoingH245Packet(MediaPacket* pPkt)
204 {
205 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
206 (0, "TscSrpBuffer::ProcessOutgoingH245Packet instance=%x, pPkt=%x",
207 this, pPkt));
208 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
209 (0, "TscSrpBuffer::ProcessOutgoingH245Packet pPkt length=%d",
210 pPkt->GetLength()));
211
212 if (iState != TscSrpBufferStarted)
213 {
214 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
215 (0, "TscSrpBuffer::ProcessOutgoingH245Packet - Error: Message received in stopped state"));
216 return;
217 }
218
219 //Allocate message and data
220 if (iTxData.GetRep() == NULL)
221 {
222 OsclSharedPtr<PVMFMediaDataImpl> data;
223
224 data = iTxPacketAlloc->allocate(MAX_TSCSRP_BUFFER_SZ);
225 if (!data)
226 {
227 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
228 PVLOGMSG_ERR, (0,
229 "TscSrpBuffer::ProcessOutgoingH245Packet - Unable allocate tx message impl"));
230 return;
231 }
232
233 iTxData = PVMFMediaData::createMediaData(data, iTxMediaMsgPoolAlloc);
234 if (!iTxData)
235 {
236 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger,
237 PVLOGMSG_ERR, (0,
238 "TscSrpBuffer::ProcessOutgoingH245Packet - Unable allocate tx message"));
239 return;
240 }
241 }
242
243 iNumMsgs++;
244
245 /* Just add the fragments to our fragment */
246 MediaFragment frag;
247 OsclRefCounterMemFrag osclFrag;
248 uint32 curSize = iTxData->getFilledSize();
249 iTxData->getMediaFragment(0, osclFrag);
250
251 for (int frag_num = 0; frag_num < pPkt->GetNumFrags(); frag_num++)
252 {
253 pPkt->GetMediaFragment(frag_num, frag);
254
255 if ((curSize + frag.GetLen()) > MAX_TSCSRP_BUFFER_SZ)
256 {
257 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
258 (0, "TscSrpBuffer::ProcessOutgoingH245Packet - Error: Buffer size exceeded"));
259 /* reset the buffer */
260 Reset();
261 return;
262 }
263 oscl_memcpy((uint8 *)osclFrag.getMemFragPtr() + curSize, frag.GetPtr(),
264 frag.GetLen());
265 curSize += frag.GetLen();
266 }
267
268 iTxData->setMediaFragFilledLen(0, curSize);
269
270 if (iEnableBuffering)
271 {
272 if (iNumMsgs == 1)
273 {
274 // start the timer
275 iTimer->Request(PV_TSC_SRP_BUFFER_TIMER_ID,
276 PV_TSC_SRP_BUFFER_TIMER_ID , 1, this);
277 }
278 }
279 else
280 {
281 // Cancel the timer
282 iTimer->Cancel(PV_TSC_SRP_BUFFER_TIMER_ID);
283 // Call the dispatch routine immediately
284 TimeoutOccurred(PV_TSC_SRP_BUFFER_TIMER_ID, 0);
285 }
286 }
287
TimeoutOccurred(int32 timerID,int32 timeoutInfo)288 void TscSrpBuffer::TimeoutOccurred(int32 timerID, int32 timeoutInfo)
289 {
290 OSCL_UNUSED_ARG(timerID);
291 OSCL_UNUSED_ARG(timeoutInfo);
292
293 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
294 (0, "TscSrpBuffer::TimeoutOccurred- iNumMsgs(%d), size(%d)\n",
295 iNumMsgs, iTxData->getFilledSize()));
296 OSCL_ASSERT(iNumMsgs);
297
298 /* Dispatch message to SRP */
299 if (iNumMsgs)
300 {
301 PVMFSharedMediaMsgPtr msg;
302
303 convertToPVMFMediaMsg(msg, iTxData);
304
305 iNumMsgs = 0;
306 iTxData.Unbind();
307 iLLPortOut->QueueOutgoingMsg(msg);
308 iLLPortOut->Send();
309 }
310 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_STACK_TRACE,
311 (0, "TscSrpBuffer::TimeoutOccurred- done"));
312
313 }
314
Start()315 void TscSrpBuffer::Start()
316 {
317 iState = TscSrpBufferStarted;
318 }
319
Stop()320 void TscSrpBuffer::Stop()
321 {
322 iState = TscSrpBufferStopped;
323 iTimer->Clear();
324 Reset();
325 }
326
Reset()327 void TscSrpBuffer::Reset()
328 {
329 iTxData.Unbind();
330 iNumMsgs = 0;
331 }
332
EnableBuffering(bool enable)333 void TscSrpBuffer::EnableBuffering(bool enable)
334 {
335 iEnableBuffering = enable;
336 }
337
ConstructL()338 void TscSrpBuffer::ConstructL()
339 {
340 iLogger = PVLogger::GetLoggerObject("3g324m.srp.tscsrpbuffer");
341
342 iTxMediaMsgPoolAlloc = OSCL_NEW(OsclMemPoolFixedChunkAllocator,
343 (NUM_TSCSRP_FRAGS, 0, &iMemAllocator));
344 OsclError::LeaveIfNull(iTxMediaMsgPoolAlloc);
345 iTxMediaDataImplMemAlloc = OSCL_NEW(OsclMemPoolFixedChunkAllocator,
346 (NUM_TSCSRP_FRAGS, 0, &iMemAllocator));
347 OsclError::LeaveIfNull(iTxMediaDataImplMemAlloc);
348 iTxPacketAlloc = OSCL_NEW(PVMFSimpleMediaBufferCombinedAlloc,
349 (iTxMediaDataImplMemAlloc));
350 OsclError::LeaveIfNull(iTxPacketAlloc);
351
352 iTimer = new OsclTimer<OsclMemAllocator>("TSCSRPBufferTimer");
353 OsclError::LeaveIfNull(iTimer);
354 iTimer->SetFrequency(1000 / TSC_SRP_BUFFER_TIMEOUT); // make timer work in 20ms intervals
355 iTimer->SetObserver(this);
356
357 iLLPortOut = OSCL_NEW(TscSrpBufferLLPortOut, ());
358 OsclError::LeaveIfNull(iLLPortOut);
359 iLLPortIn = TscSrpBufferLLPortIn::NewL(this);
360
361 iH245Interface = this;
362 }
363
364
365
366