• 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 #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