1 /* |
|
2 * Copyright (c) 2007 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 the License "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: Class that reads RTP packets from propriatary file format.* |
|
15 */ |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include "CCRRtpFileSource.h" |
|
22 #include <ipvideo/CRtpClipHandler.h> |
|
23 #include "CCRPacketBuffer.h" |
|
24 #include "videoserviceutilsLogger.h" |
|
25 |
|
26 // CONSTANTS |
|
27 const TInt KGroupsCountPoint( 0 ); |
|
28 const TInt KBufferThesholdCount( 20 ); |
|
29 |
|
30 // ============================ MEMBER FUNCTIONS =============================== |
|
31 |
|
32 // ----------------------------------------------------------------------------- |
|
33 // CCRRtpFileSource::NewL |
|
34 // Two-phased constructor. |
|
35 // ----------------------------------------------------------------------------- |
|
36 // |
|
37 CCRRtpFileSource* CCRRtpFileSource::NewL( |
|
38 const SCRRtpPlayParams& aParams, |
|
39 CRtpClipHandler*& aClipHandler, |
|
40 MCRStreamObserver& aSessionObs, |
|
41 CCRStreamingSession& aOwningSession ) |
|
42 { |
|
43 CCRRtpFileSource* self = new( ELeave ) |
|
44 CCRRtpFileSource( aClipHandler, aSessionObs, aOwningSession ); |
|
45 CleanupStack::PushL( self ); |
|
46 self->ConstructL( aParams ); |
|
47 CleanupStack::Pop(); |
|
48 return self; |
|
49 } |
|
50 |
|
51 // ----------------------------------------------------------------------------- |
|
52 // CCRRtpFileSource::NewL |
|
53 // Two-phased constructor. |
|
54 // ----------------------------------------------------------------------------- |
|
55 // |
|
56 CCRRtpFileSource* CCRRtpFileSource::NewL( |
|
57 const RFile& aRtpHandle, |
|
58 CRtpClipHandler*& aClipHandler, |
|
59 MCRStreamObserver& aSessionObs, |
|
60 CCRStreamingSession& aOwningSession ) |
|
61 { |
|
62 CCRRtpFileSource* self = new( ELeave ) |
|
63 CCRRtpFileSource( aClipHandler, aSessionObs, aOwningSession ); |
|
64 CleanupStack::PushL( self ); |
|
65 self->ConstructL( aRtpHandle ); |
|
66 CleanupStack::Pop(); |
|
67 return self; |
|
68 } |
|
69 |
|
70 // ----------------------------------------------------------------------------- |
|
71 // CCRRtpFileSource::CCRRtpFileSource |
|
72 // C++ default constructor can NOT contain any code, that might leave. |
|
73 // ----------------------------------------------------------------------------- |
|
74 // |
|
75 CCRRtpFileSource::CCRRtpFileSource( |
|
76 CRtpClipHandler*& aClipHandler, |
|
77 MCRStreamObserver& aSessionObs, |
|
78 CCRStreamingSession& aOwningSession ) |
|
79 : CCRPacketSourceBase( aOwningSession, CCRStreamingSession::ECRRtpSourceId ), |
|
80 iClipHandler( aClipHandler ), |
|
81 iSessionObs( aSessionObs ), |
|
82 iInitialTime( KMaxTUint ), |
|
83 iClipPauseSent( 0 ) |
|
84 { |
|
85 // None |
|
86 } |
|
87 |
|
88 // ----------------------------------------------------------------------------- |
|
89 // CCRRtpFileSource::ConstructL |
|
90 // Symbian 2nd phase constructor can leave. |
|
91 // ----------------------------------------------------------------------------- |
|
92 // |
|
93 void CCRRtpFileSource::ConstructL( const SCRRtpPlayParams& aParams ) |
|
94 { |
|
95 const TBool timeShift( |
|
96 aParams.iFileName.Find( KDvrTimeShiftFile ) > KErrNotFound ); |
|
97 LOG1( "CCRRtpFileSource::ConstructL() in, timeShift: %d", timeShift ); |
|
98 |
|
99 // RTP clip handler |
|
100 User::LeaveIfNull( iClipHandler ); |
|
101 iClipHandler->RegisterReadObserver( this ); |
|
102 iClipHandler->StartPlayBackL( aParams, timeShift ); |
|
103 |
|
104 LOG( "CCRRtpFileSource::ConstructL() out" ); |
|
105 } |
|
106 |
|
107 // ----------------------------------------------------------------------------- |
|
108 // CCRRtpFileSource::ConstructL |
|
109 // Symbian 2nd phase constructor can leave. |
|
110 // ----------------------------------------------------------------------------- |
|
111 // |
|
112 void CCRRtpFileSource::ConstructL( const RFile& aRtpHandle ) |
|
113 { |
|
114 LOG( "CCRRtpFileSource::ConstructL() in" ); |
|
115 |
|
116 User::LeaveIfNull( iClipHandler ); |
|
117 iClipHandler->RegisterReadObserver( this ); |
|
118 iClipHandler->StartPlayBackL( aRtpHandle ); |
|
119 |
|
120 LOG( "CCRRtpFileSource::ConstructL() out" ); |
|
121 } |
|
122 |
|
123 // ----------------------------------------------------------------------------- |
|
124 // CCRRtpFileSource::~CCRRtpFileSource |
|
125 // Destructor. |
|
126 // ----------------------------------------------------------------------------- |
|
127 // |
|
128 CCRRtpFileSource::~CCRRtpFileSource() |
|
129 { |
|
130 LOG( "CCRRtpFileSource::~CCRRtpFileSource()" ); |
|
131 |
|
132 if ( iClipHandler ) |
|
133 { |
|
134 iClipHandler->StopPlayBack( KErrNone, 0 ); |
|
135 } |
|
136 |
|
137 delete iSdp; |
|
138 } |
|
139 |
|
140 // ----------------------------------------------------------------------------- |
|
141 // CCRRtpFileSource::GetSdp |
|
142 // ----------------------------------------------------------------------------- |
|
143 // |
|
144 TInt CCRRtpFileSource::GetSdp( TPtrC8& aSdp ) |
|
145 { |
|
146 if ( iSdp ) |
|
147 { |
|
148 aSdp.Set( iSdp->Des() ); |
|
149 return KErrNone; |
|
150 } |
|
151 |
|
152 return KErrNotReady; |
|
153 } |
|
154 |
|
155 // ----------------------------------------------------------------------------- |
|
156 // CCRRtpFileSource::SetBuffer |
|
157 // ----------------------------------------------------------------------------- |
|
158 // |
|
159 void CCRRtpFileSource::SetBuffer( CCRPacketBuffer* aBuffer ) |
|
160 { |
|
161 iBuffer = aBuffer; |
|
162 iBuffer->ContinousStream( EFalse ); |
|
163 iBuffer->MoreComing( EFalse ); |
|
164 } |
|
165 |
|
166 // ----------------------------------------------------------------------------- |
|
167 // CCRRtpFileSource::PostActionL |
|
168 // ----------------------------------------------------------------------------- |
|
169 // |
|
170 void CCRRtpFileSource::PostActionL() |
|
171 { |
|
172 LOG( "CCRRtpFileSource::PostActionL(), SDP will be handled !" ); |
|
173 |
|
174 // SDP |
|
175 if ( iClipHandler ) |
|
176 { |
|
177 iSdp = iClipHandler->GetClipSdpL(); |
|
178 } |
|
179 |
|
180 // Notify that SDP available |
|
181 iSessionObs.StatusChanged( MCRPacketSource::ERtpStateSdpAvailable ); |
|
182 delete iSdp; iSdp = NULL; |
|
183 } |
|
184 |
|
185 // ----------------------------------------------------------------------------- |
|
186 // CCRRtpFileSource::Restore |
|
187 // ----------------------------------------------------------------------------- |
|
188 // |
|
189 void CCRRtpFileSource::Restore() |
|
190 { |
|
191 const TInt err( NextClipGroup( ETrue ) ); |
|
192 if ( err && err != KErrEof ) |
|
193 { |
|
194 LOG1( "CCRRtpFileSource::Restore(), NextClipGroup() err: %d", err ); |
|
195 iSessionObs.StatusChanged( MCRPacketSource::ERtpStateClosing ); |
|
196 } |
|
197 } |
|
198 |
|
199 // ----------------------------------------------------------------------------- |
|
200 // CCRRtpFileSource::Play |
|
201 // |
|
202 // ----------------------------------------------------------------------------- |
|
203 // |
|
204 TInt CCRRtpFileSource::Play( const TReal& aStartPos, const TReal& aEndPos ) |
|
205 { |
|
206 LOG3( "CCRRtpFileSource::Play(), aStartPos: %f, aEndPos: %f, iClipPauseSent: %d", |
|
207 aStartPos, aEndPos, iClipPauseSent ); |
|
208 // Play for player? |
|
209 if ( aStartPos == KRealZero && aEndPos == KRealZero ) |
|
210 { |
|
211 iInitialTime = KMaxTUint; |
|
212 return NextClipGroup( EFalse ); |
|
213 } |
|
214 |
|
215 // Loading started in player? |
|
216 if ( aStartPos == KRealMinusOne && aEndPos == KRealMinusOne ) |
|
217 { |
|
218 const TBool pauseSent( iClipPauseSent > 0 ); |
|
219 if ( pauseSent ) |
|
220 { |
|
221 iClipPauseSent--; |
|
222 iBuffer->ResetBuffer(); |
|
223 } |
|
224 |
|
225 // Read more from clip |
|
226 TInt err( NextClipGroup( EFalse ) ); |
|
227 if ( !err && pauseSent ) |
|
228 { |
|
229 iInitialTime = KMaxTUint; |
|
230 err = ECRStreamPauseHanling; |
|
231 LOG( "CCRRtpFileSource::Play(), ECRStreamPauseHanling" ); |
|
232 } |
|
233 else |
|
234 { |
|
235 if ( err == KErrEof ) |
|
236 { |
|
237 err = KErrNone; |
|
238 if ( iClipHandler ) |
|
239 { |
|
240 TRAP( err, iClipHandler->SetSeekPointL( 0 ) ); |
|
241 } |
|
242 if ( !err ) |
|
243 { |
|
244 err = ECRStreamEndHandling; |
|
245 LOG( "CCRRtpFileSource::Play(), ECRStreamEndHandling" ); |
|
246 } |
|
247 } |
|
248 } |
|
249 |
|
250 return err; |
|
251 } |
|
252 |
|
253 return KErrCompletion; |
|
254 } |
|
255 |
|
256 // ----------------------------------------------------------------------------- |
|
257 // CCRRtpFileSource::Stop |
|
258 // ----------------------------------------------------------------------------- |
|
259 // |
|
260 TInt CCRRtpFileSource::Stop() |
|
261 { |
|
262 LOG( "CCRRtpFileSource::Stop()" ); |
|
263 |
|
264 return RtpPosition( 0 ); |
|
265 } |
|
266 |
|
267 // ----------------------------------------------------------------------------- |
|
268 // CCRRtpFileSource::SetPosition |
|
269 // |
|
270 // ----------------------------------------------------------------------------- |
|
271 // |
|
272 TInt CCRRtpFileSource::SetPosition( const TInt64 aPosition ) |
|
273 { |
|
274 TInt err( RtpPosition( TUint( aPosition / KSiKilo ) ) ); |
|
275 if ( !err ) |
|
276 { |
|
277 err = NextClipGroup( EFalse ); |
|
278 } |
|
279 |
|
280 return err; |
|
281 } |
|
282 |
|
283 // ----------------------------------------------------------------------------- |
|
284 // CCRRtpFileSource::GetPosition |
|
285 // |
|
286 // ----------------------------------------------------------------------------- |
|
287 // |
|
288 TInt CCRRtpFileSource::GetPosition( TInt64& aPosition, TInt64& aDuration ) |
|
289 { |
|
290 if ( iBuffer && iClipHandler ) |
|
291 { |
|
292 if ( iInitialTime != KMaxTUint ) |
|
293 { |
|
294 aPosition += TInt64( iInitialTime ) * KSiKilo; |
|
295 } |
|
296 else |
|
297 { |
|
298 LOG( "CCRRtpFileSource::GetPosition(), iInitialTime not valid !" ); |
|
299 } |
|
300 |
|
301 aDuration = TInt64( iClipHandler->GetCurrentLength() ) * KSiKilo; |
|
302 #ifdef CR_ALL_LOGS |
|
303 LOG2( "CCRRtpFileSource::GetPosition(), aPosition: %u, aDuration: %u", |
|
304 ( TUint )( aPosition / KSiKilo ), ( TUint )( aDuration / KSiKilo ) ); |
|
305 #endif // CR_ALL_LOGS |
|
306 return KErrNone; |
|
307 } |
|
308 |
|
309 return KErrCompletion; |
|
310 } |
|
311 |
|
312 // ----------------------------------------------------------------------------- |
|
313 // CCRRtpFileSource::GroupReadedL |
|
314 // Adds packets to the buffer when finished asyncronous group reading. |
|
315 // ----------------------------------------------------------------------------- |
|
316 // |
|
317 void CCRRtpFileSource::GroupReadedL( |
|
318 const TDesC8& aGroup, |
|
319 const TUint aGroupTime, |
|
320 const TBool aLastGroup ) |
|
321 { |
|
322 // Group time |
|
323 if ( iInitialTime == KMaxTUint ) |
|
324 { |
|
325 iInitialTime = aGroupTime; |
|
326 } |
|
327 |
|
328 // Data valid? |
|
329 TInt point( KGroupsCountPoint + KPacketsCountBytes ); |
|
330 const TInt total( aGroup.Length() ); |
|
331 if ( point > total ) |
|
332 { |
|
333 LOG( "CCRRtpFileSource::GroupReadedL(), No Packets Total Count !" ); |
|
334 User::Leave( KErrCorrupt ); |
|
335 } |
|
336 |
|
337 // Packets total count (PTC) |
|
338 const TInt totalCount( CRtpUtil::GetValueL( |
|
339 aGroup.Mid( KGroupsCountPoint, KPacketsCountBytes ) ) ); |
|
340 if ( totalCount > 0 ) |
|
341 { |
|
342 iBuffer->MoreComing( ETrue ); |
|
343 } |
|
344 |
|
345 // Loop all packets |
|
346 for ( TInt i( 0 ); i < totalCount; i++ ) |
|
347 { |
|
348 // Corrupted? |
|
349 if ( ( point + KPacketSizeBytesLen ) > total ) |
|
350 { |
|
351 LOG( "CCRRtpFileSource::GroupReadedL(), No Packets Size !" ); |
|
352 User::Leave( KErrCorrupt ); |
|
353 } |
|
354 |
|
355 // Packet total Size (PTS) |
|
356 TInt packetSize( CRtpUtil::GetValueL( |
|
357 aGroup.Mid( point, KPacketSizeBytesLen ) ) ); |
|
358 // Corrupted? |
|
359 if ( packetSize <= 0 || ( point + packetSize ) > total ) |
|
360 { |
|
361 LOG( "CCRRtpFileSource::GroupReadedL(), No Packets Payload !" ); |
|
362 User::Leave( KErrCorrupt ); |
|
363 } |
|
364 |
|
365 // Packet type |
|
366 point += KPacketSizeBytesLen; |
|
367 const MRtpFileWriteObserver::TRtpType type( |
|
368 ( MRtpFileWriteObserver::TRtpType )( aGroup[point] ) ); |
|
369 point += KPacketTypeBytesLen; |
|
370 packetSize -= ( KPacketSizeBytesLen + KPacketTypeBytesLen ); |
|
371 |
|
372 // Insert packet to the buffer |
|
373 const TPtrC8 packet( aGroup.Mid( point, packetSize ) ); |
|
374 |
|
375 #ifdef CR_ALL_LOGS |
|
376 const TUint8* pointer( &packet[2] ); |
|
377 TInt seq( BigEndian::Get16( pointer ) ); |
|
378 LOG3( "CCRRtpFileSource::GroupReadedL(), type: %d, packet: %d, seq: %d", |
|
379 type, packet.Length(), seq ); |
|
380 //RFileLogger::WriteFormat( _L( "livetv" ), _L( "play.log" ), EFileLoggingModeAppend, |
|
381 // _L( "GroupReadedL(), type: %d, packet: %d, seq: %d" ), type, packet.Length(), seq ); |
|
382 #endif // CR_ALL_LOGS |
|
383 |
|
384 MCRPacketSource::TCRPacketStreamId stream( MCRPacketSource::EStreamIdCount ); |
|
385 if ( TypeToStream( type, stream ) ) |
|
386 { |
|
387 // Last packet in group? |
|
388 if ( i >= ( totalCount - 1 ) ) |
|
389 { |
|
390 iBuffer->MoreComing( EFalse ); |
|
391 if ( aLastGroup && stream != MCRPacketSource::EStreamEndTag ) |
|
392 { |
|
393 LOG( "CCRRtpFileSource::GroupReadedL(), Misses last group from clip !" ); |
|
394 stream = MCRPacketSource::EStreamEndTag; |
|
395 } |
|
396 } |
|
397 |
|
398 // Packet to buffer |
|
399 iBuffer->AddPacket( stream, packet ); |
|
400 } |
|
401 |
|
402 point+= packetSize; |
|
403 } |
|
404 } |
|
405 |
|
406 // ----------------------------------------------------------------------------- |
|
407 // CCRRtpFileSource::ReadStatus |
|
408 // ----------------------------------------------------------------------------- |
|
409 // |
|
410 void CCRRtpFileSource::ReadStatus( TInt aStatus ) |
|
411 { |
|
412 LOG1( "CCRRtpFileSource::ReadStatus(), aStatus: %d", aStatus ); |
|
413 |
|
414 switch ( aStatus ) |
|
415 { |
|
416 case MRtpFileReadObserver::ERtpTimeShifTEnd: |
|
417 break; |
|
418 |
|
419 default: |
|
420 iSessionObs.StatusChanged( MCRPacketSource::ERtpStateClosing ); |
|
421 break; |
|
422 } |
|
423 } |
|
424 |
|
425 // ----------------------------------------------------------------------------- |
|
426 // CCRRtpFileSource::NextClipGroup |
|
427 // ----------------------------------------------------------------------------- |
|
428 // |
|
429 TInt CCRRtpFileSource::NextClipGroup( const TBool aForce ) |
|
430 { |
|
431 if ( iBuffer && iClipHandler ) |
|
432 { |
|
433 if ( aForce || iBuffer->PacketsMinCount() < KBufferThesholdCount ) |
|
434 { |
|
435 TRAPD( err, iClipHandler->NextClipGroupL() ); |
|
436 return err; |
|
437 } |
|
438 |
|
439 return KErrNone; |
|
440 } |
|
441 |
|
442 return KErrNotReady; |
|
443 } |
|
444 |
|
445 // ----------------------------------------------------------------------------- |
|
446 // CCRRtpFileSource::RtpPosition |
|
447 // ----------------------------------------------------------------------------- |
|
448 // |
|
449 TInt CCRRtpFileSource::RtpPosition( const TUint aPosition ) |
|
450 { |
|
451 LOG1( "CCRRtpFileSource::RtpPosition(), aPosition: %d", aPosition ); |
|
452 |
|
453 TInt err( KErrCompletion ); |
|
454 if ( iBuffer && iClipHandler ) |
|
455 { |
|
456 TRAP( err, iClipHandler->SetSeekPointL( aPosition ) ); |
|
457 if ( !err ) |
|
458 { |
|
459 iInitialTime = KMaxTUint; |
|
460 iBuffer->ResetBuffer(); |
|
461 } |
|
462 } |
|
463 |
|
464 return err; |
|
465 } |
|
466 |
|
467 // ----------------------------------------------------------------------------- |
|
468 // CCRRtpFileSource::TypeToStream |
|
469 // ----------------------------------------------------------------------------- |
|
470 // |
|
471 TBool CCRRtpFileSource::TypeToStream( |
|
472 const MRtpFileWriteObserver::TRtpType& aType, |
|
473 MCRPacketSource::TCRPacketStreamId& aStream ) |
|
474 { |
|
475 switch ( aType ) |
|
476 { |
|
477 case MRtpFileWriteObserver::ERtpAudio: |
|
478 aStream = MCRPacketSource::EAudioStream; |
|
479 break; |
|
480 |
|
481 case MRtpFileWriteObserver::ERtcpAudio: |
|
482 aStream = MCRPacketSource::EAudioControlStream; |
|
483 break; |
|
484 |
|
485 case MRtpFileWriteObserver::ERtpVideo: |
|
486 aStream = MCRPacketSource::EVideoStream; |
|
487 break; |
|
488 |
|
489 case MRtpFileWriteObserver::ERtcpVideo: |
|
490 aStream = MCRPacketSource::EVideoControlStream; |
|
491 break; |
|
492 |
|
493 case MRtpFileWriteObserver::ERtpSubTitle: |
|
494 aStream = MCRPacketSource::ESubTitleStream; |
|
495 break; |
|
496 |
|
497 case MRtpFileWriteObserver::ERtcpSubTitle: |
|
498 aStream = MCRPacketSource::ESubTitleControlStream; |
|
499 break; |
|
500 |
|
501 case MRtpFileWriteObserver::ERtpClipPause: |
|
502 LOG( "CCRRtpFileSource::TypeToStream(), ERtpClipPause" ); |
|
503 iClipPauseSent = ETrue; |
|
504 aStream = MCRPacketSource::EDisContinousStream; |
|
505 break; |
|
506 |
|
507 case MRtpFileWriteObserver::ERtpClipEnd: |
|
508 LOG( "CCRRtpFileSource::TypeToStream(), ERtpClipEnd" ); |
|
509 aStream = MCRPacketSource::EStreamEndTag; |
|
510 break; |
|
511 |
|
512 default: |
|
513 LOG1( "CCRRtpFileSource::TypeToStream(), Default case, aType: %d", |
|
514 aType ); |
|
515 return EFalse; |
|
516 } |
|
517 |
|
518 return ETrue; |
|
519 } |
|
520 |
|
521 // End of File |
|