|
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: Implementation of the DVB-H Recording Manager RTP read class.* |
|
15 */ |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include "CRtpToFile.h" |
|
22 #include "CRtpFromFile.h" |
|
23 #include <ipvideo/CRtpMetaHeader.h> |
|
24 #include <ipvideo/CRtpClipManager.h> |
|
25 #include "CRtpTimer.h" |
|
26 #include <bsp.h> |
|
27 #include "videoserviceutilsLogger.h" |
|
28 |
|
29 // CONSTANTS |
|
30 const TInt KReadTimerInterval( 1000 ); |
|
31 |
|
32 // ============================ MEMBER FUNCTIONS =============================== |
|
33 |
|
34 // ----------------------------------------------------------------------------- |
|
35 // CRtpFromFile::NewL |
|
36 // Static two-phased constructor. Leaves object to cleanup stack. |
|
37 // ----------------------------------------------------------------------------- |
|
38 // |
|
39 CRtpFromFile* CRtpFromFile::NewL( |
|
40 MRtpFileReadObserver& aReadObs, |
|
41 CRtpToFile* aToFile ) |
|
42 { |
|
43 CRtpFromFile* self = new( ELeave ) CRtpFromFile( aReadObs, aToFile ); |
|
44 CleanupStack::PushL( self ); |
|
45 self->ConstructL(); |
|
46 CleanupStack::Pop( self ); |
|
47 return self; |
|
48 } |
|
49 |
|
50 // ----------------------------------------------------------------------------- |
|
51 // CRtpFromFile::CRtpFromFile |
|
52 // C++ default constructor can NOT contain any code, that might leave. |
|
53 // ----------------------------------------------------------------------------- |
|
54 // |
|
55 CRtpFromFile::CRtpFromFile( MRtpFileReadObserver& aReadObs, CRtpToFile* aToFile ) |
|
56 : CRtpFileBase(), |
|
57 iReadObs( aReadObs ), |
|
58 iToFile( aToFile ), |
|
59 iSkippedRead( EFalse ), |
|
60 iDuration( 0 ) |
|
61 { |
|
62 // None |
|
63 } |
|
64 |
|
65 // ----------------------------------------------------------------------------- |
|
66 // CRtpFromFile::ConstructL |
|
67 // Symbian 2nd phase constructor can leave. |
|
68 // ----------------------------------------------------------------------------- |
|
69 // |
|
70 void CRtpFromFile::ConstructL() |
|
71 { |
|
72 LOG( "CRtpFromFile::ConstructL()" ); |
|
73 |
|
74 CRtpFileBase::ConstructL(); |
|
75 } |
|
76 |
|
77 // ----------------------------------------------------------------------------- |
|
78 // Destructor |
|
79 // |
|
80 CRtpFromFile::~CRtpFromFile() |
|
81 // ----------------------------------------------------------------------------- |
|
82 { |
|
83 LOG( "CRtpFromFile::~CRtpFromFile()" ); |
|
84 |
|
85 Cancel(); |
|
86 delete iTimer; iTimer = NULL; |
|
87 delete iFileData; iFileData = NULL; |
|
88 } |
|
89 |
|
90 // ----------------------------------------------------------------------------- |
|
91 // CRtpFromFile::InitRtpReadL |
|
92 // Sets path of RTP file. |
|
93 // ----------------------------------------------------------------------------- |
|
94 // |
|
95 void CRtpFromFile::InitRtpReadL( |
|
96 const TDesC& aClipPath, |
|
97 TInt8& aVersion, |
|
98 const TBool aTimeShift ) |
|
99 { |
|
100 LOG1( "CRtpFromFile::InitRtpReadL(), aClipPath: %S", &aClipPath ); |
|
101 |
|
102 // File server |
|
103 if ( !iFs.Handle() ) |
|
104 { |
|
105 User::LeaveIfError( iFs.Connect() ); |
|
106 } |
|
107 |
|
108 // Open clip |
|
109 aVersion = SwapClipL( aClipPath ); |
|
110 |
|
111 // Mode |
|
112 iMode = ( aTimeShift )? EModeTimeShift: EModeNormal; |
|
113 |
|
114 #ifdef CR_ALL_LOGS |
|
115 LogVariables( _L( "InitRtpReadL()" ) ); |
|
116 #endif // CR_ALL_LOGS |
|
117 } |
|
118 |
|
119 // ----------------------------------------------------------------------------- |
|
120 // CRtpFromFile::InitRtpReadL |
|
121 // Sets path of RTP file. |
|
122 // ----------------------------------------------------------------------------- |
|
123 // |
|
124 void CRtpFromFile::InitRtpReadL( |
|
125 const RFile& aFileHandle, |
|
126 TInt8& aVersion ) |
|
127 { |
|
128 LOG( "CRtpFromFile::InitRtpReadL(), with handle" ); |
|
129 |
|
130 // File handle |
|
131 if ( !iFs.Handle() ) |
|
132 { |
|
133 User::LeaveIfError( iFs.Connect() ); |
|
134 } |
|
135 |
|
136 // Duplicate handle |
|
137 iFile.Close(); |
|
138 iFile.Duplicate( aFileHandle ); |
|
139 |
|
140 // File header |
|
141 ReadClipHeaderL( aVersion ); |
|
142 delete iCurrentPath; iCurrentPath = NULL; |
|
143 TFileName name( KNullDesC ); |
|
144 iFile.FullName( name ); |
|
145 iCurrentPath = name.AllocL(); |
|
146 |
|
147 // Mode |
|
148 iMode = EModeNormal; |
|
149 |
|
150 #ifdef CR_ALL_LOGS |
|
151 LogVariables( _L( "InitRtpReadL()" ) ); |
|
152 #endif // CR_ALL_LOGS |
|
153 } |
|
154 |
|
155 // ----------------------------------------------------------------------------- |
|
156 // CRtpFromFile::SwapClipL |
|
157 // Sets new path of RTP file. |
|
158 // ----------------------------------------------------------------------------- |
|
159 // |
|
160 TInt8 CRtpFromFile::SwapClipL( const TDesC& aClipPath ) |
|
161 { |
|
162 LOG1( "CRtpFromFile::SwapClipL(), aClipPath: %S", &aClipPath ); |
|
163 |
|
164 iFile.Close(); |
|
165 if ( !iFs.Handle() ) |
|
166 { |
|
167 User::Leave( KErrBadHandle ); |
|
168 } |
|
169 |
|
170 // Delete used clip |
|
171 if ( iMode == EModeTimeShift ) |
|
172 { |
|
173 iFs.Delete( *iCurrentPath ); |
|
174 } |
|
175 |
|
176 // Open new |
|
177 User::LeaveIfError( iFile.Open( iFs, aClipPath, |
|
178 EFileShareAny | EFileStream | EFileRead ) ); |
|
179 // File header |
|
180 TInt8 version( 0 ); |
|
181 ReadClipHeaderL( version ); |
|
182 delete iCurrentPath; iCurrentPath = NULL; |
|
183 iCurrentPath = aClipPath.AllocL(); |
|
184 |
|
185 return version; |
|
186 } |
|
187 |
|
188 // ----------------------------------------------------------------------------- |
|
189 // CRtpFromFile::ReadNextGroupL |
|
190 // Reads next RTP packets group from a specified file. |
|
191 // ----------------------------------------------------------------------------- |
|
192 // |
|
193 TInt CRtpFromFile::ReadNextGroupL( const TInt aGroupPoint ) |
|
194 { |
|
195 User::LeaveIfError( iMode ); |
|
196 TBool delayedRead( EFalse ); |
|
197 |
|
198 // Allready active?? |
|
199 if ( iFileData ) |
|
200 { |
|
201 if ( iTimer || IsActive() ) |
|
202 { |
|
203 return KErrInUse; // Read already started, indication, not error |
|
204 } |
|
205 else |
|
206 { |
|
207 // Packet read may happen during iReadObs.RtpGroupReaded() call |
|
208 LOG( "CRtpFromFile::ReadNextGroupL(), Delayed read !" ); |
|
209 delayedRead = ETrue; |
|
210 } |
|
211 } |
|
212 |
|
213 // Is watch during recording too close to live? |
|
214 if ( iToFile && iNextGroupPoint >= LastSeekAddr() ) |
|
215 { |
|
216 iSkippedRead = ETrue; |
|
217 LOG( "CRtpFromFile::ReadNextGroupL(), Too close to live !" ); |
|
218 return KErrEof; // No read actions now, indication, not error |
|
219 } |
|
220 |
|
221 // Group |
|
222 iThisGroup = ( aGroupPoint > KErrNotFound )? aGroupPoint: iNextGroupPoint; |
|
223 |
|
224 // Ok to read more? |
|
225 if ( iThisGroup > iLastSeekAddr || iGroupTime >= iDuration ) |
|
226 { |
|
227 LOG( "CRtpFromFile::ReadNextGroupL(), All packets readed !" ); |
|
228 User::Leave( KErrEof ); |
|
229 } |
|
230 |
|
231 // Read group |
|
232 if ( delayedRead ) |
|
233 { |
|
234 delete iTimer; iTimer = NULL; |
|
235 iTimer = CRtpTimer::NewL( *this ); |
|
236 iTimer->After( KReadTimerInterval ); |
|
237 } |
|
238 else |
|
239 { |
|
240 ReadGroupHeaderL(); |
|
241 ReadNextGroupFromFileL(); |
|
242 } |
|
243 |
|
244 return KErrNone; |
|
245 } |
|
246 |
|
247 // ----------------------------------------------------------------------------- |
|
248 // CRtpFromFile::GetClipSdpL |
|
249 // Reads SDP from a current clip. SDP is stored to meta header during recording. |
|
250 // ----------------------------------------------------------------------------- |
|
251 // |
|
252 HBufC8* CRtpFromFile::GetClipSdpL() |
|
253 { |
|
254 User::LeaveIfError( iMode ); |
|
255 CRtpMetaHeader* metaheader = CRtpMetaHeader::NewLC( |
|
256 iFile, CRtpMetaHeader::EMetaRead ); |
|
257 HBufC8* sdp = metaheader->ReadSdpDataL(); |
|
258 CleanupStack::PopAndDestroy( metaheader ); |
|
259 return sdp; |
|
260 } |
|
261 |
|
262 // ----------------------------------------------------------------------------- |
|
263 // CRtpFromFile::ReadSkippedGroup |
|
264 // Reads one RTP packet from a specified file if previous read was skipped. |
|
265 // ----------------------------------------------------------------------------- |
|
266 // |
|
267 void CRtpFromFile::ReadSkippedGroup() |
|
268 { |
|
269 if ( iSkippedRead && iNextGroupPoint < LastSeekAddr() && |
|
270 iMode != EModeNone && iFileData != NULL ) |
|
271 { |
|
272 iSkippedRead = EFalse; |
|
273 iThisGroup = iNextGroupPoint; |
|
274 TRAP_IGNORE( ReadGroupHeaderL(); |
|
275 ReadNextGroupFromFileL() ); |
|
276 } |
|
277 } |
|
278 |
|
279 // ----------------------------------------------------------------------------- |
|
280 // CRtpFromFile::UpdateLastSeekAddr |
|
281 // Updates final last seek addres from clip write when recording stopped. |
|
282 // ----------------------------------------------------------------------------- |
|
283 // |
|
284 void CRtpFromFile::UpdateLastSeekAddr() |
|
285 { |
|
286 if ( iToFile ) |
|
287 { |
|
288 iDuration = iToFile->GetCurrentLength(); |
|
289 iLastSeekAddr = iToFile->LastSeekAddr(); |
|
290 |
|
291 LOG2( "CRtpFromFile::UpdateLastSeekAddr(), iLastSeekAddr: %d, iDuration: %d", |
|
292 iLastSeekAddr, iDuration ); |
|
293 // Recording is stopped |
|
294 iToFile = NULL; |
|
295 } |
|
296 } |
|
297 |
|
298 // ----------------------------------------------------------------------------- |
|
299 // CRtpFromFile::SetSeekPointL |
|
300 // Sets the seek point of the clip. |
|
301 // ----------------------------------------------------------------------------- |
|
302 // |
|
303 void CRtpFromFile::SetSeekPointL( const TUint aTime ) |
|
304 { |
|
305 Cancel(); |
|
306 delete iTimer; iTimer = NULL; |
|
307 delete iFileData; iFileData = NULL; |
|
308 User::LeaveIfError( iMode ); |
|
309 |
|
310 // Group from the seek array, accuracy 30s |
|
311 iThisGroup = FindSeekGroup( aTime, ( iToFile )? iToFile->SeekArray(): iSeekArray ); |
|
312 LOG2( "CRtpFromFile::SetSeekPointL(), aTime: %d, group from seek array: %d", |
|
313 aTime, iThisGroup ); |
|
314 if ( iThisGroup == KErrNotFound ) |
|
315 { |
|
316 iThisGroup = iFirstSeekAddr; |
|
317 } |
|
318 ReadGroupHeaderL(); |
|
319 |
|
320 // Find group basing on the seek time, accuracy 0 - 3 s |
|
321 if ( aTime > 0 ) |
|
322 { |
|
323 while ( aTime > iGroupTime && iNextGroupPoint < iLastSeekAddr ) |
|
324 { |
|
325 // Next group |
|
326 iThisGroup = iNextGroupPoint; |
|
327 ReadGroupHeaderL(); |
|
328 #ifdef CR_ALL_LOGS |
|
329 LOG2( "CRtpFromFile::SetSeekPointL(), iThisGroup: %u, iGroupTime: %u", |
|
330 iThisGroup, iGroupTime ); |
|
331 #endif // CR_ALL_LOGS |
|
332 } |
|
333 } |
|
334 |
|
335 // Prepare for next read, one extra group back looks better |
|
336 iNextGroupPoint = ( iPrevGroupPoint > iFirstSeekAddr ) ? |
|
337 iPrevGroupPoint : iThisGroup; |
|
338 delete iFileData; iFileData = NULL; |
|
339 |
|
340 LOG1( "CRtpFromFile::SetSeekPointL(), iNextGroupPoint: %d", |
|
341 iNextGroupPoint ); |
|
342 } |
|
343 |
|
344 // ----------------------------------------------------------------------------- |
|
345 // CRtpFromFile::StopRtpRead |
|
346 // Stops file reading. |
|
347 // ----------------------------------------------------------------------------- |
|
348 // |
|
349 void CRtpFromFile::StopRtpRead( const TInt aStatus, const TUint aPlayerBuf ) |
|
350 { |
|
351 LOG2( "CRtpFromFile::StopRtpRead(), aStatus: %d, aPlayerBuf: %u", |
|
352 aStatus, aPlayerBuf ); |
|
353 LOG2( "CRtpFromFile::StopRtpRead(), iMode: %d, iGroupTime: %d", |
|
354 iMode, iGroupTime ); |
|
355 Cancel(); |
|
356 if ( iMode != EModeNone ) |
|
357 { |
|
358 iFile.ReadCancel(); |
|
359 |
|
360 #ifdef CR_ALL_LOGS |
|
361 LogVariables( _L( "StopRtpRead()" ) ); |
|
362 #endif // CR_ALL_LOGS |
|
363 } |
|
364 |
|
365 delete iTimer; iTimer = NULL; |
|
366 delete iFileData; iFileData = NULL; |
|
367 if ( iMode == EModeNormal || iMode == EModeHandle ) |
|
368 { |
|
369 // Try to seek back to what user sees for continue play spot |
|
370 if ( !aStatus & iThisGroup > 0 && iThisGroup < iLastSeekAddr ) |
|
371 { |
|
372 const TInt thisGroup( iThisGroup ); |
|
373 TRAPD( err, SetSeekPointL( iGroupTime - aPlayerBuf ) ); |
|
374 if ( err ) |
|
375 { |
|
376 LOG1( "CRtpFromFile::StopRtpRead(), SetSeekPointL Leaved: %d", err ); |
|
377 iThisGroup = thisGroup; |
|
378 } |
|
379 } |
|
380 |
|
381 // Update meta header if no error |
|
382 if ( !aStatus ) |
|
383 { |
|
384 TInt err ( KErrNone ); |
|
385 if ( iToFile ) |
|
386 { |
|
387 TRAP( err, iToFile->UpdatePlayAttL( iThisGroup ) ); |
|
388 } |
|
389 else |
|
390 { |
|
391 TRAP( err, UpdatePlayAttL() ); |
|
392 } |
|
393 |
|
394 // Possible error ignored |
|
395 if ( err ) |
|
396 { |
|
397 LOG1( "CRtpFromFile::StopRtpRead(), UpdatePlayAttL Leaved: %d", err ); |
|
398 } |
|
399 } |
|
400 } |
|
401 |
|
402 iMode = EModeNone; |
|
403 iFile.Close(); |
|
404 } |
|
405 |
|
406 // ----------------------------------------------------------------------------- |
|
407 // CRtpFromFile::RunL |
|
408 // ----------------------------------------------------------------------------- |
|
409 // |
|
410 void CRtpFromFile::RunL() |
|
411 { |
|
412 User::LeaveIfError( iStatus.Int() ); |
|
413 |
|
414 // All groups readed? |
|
415 if ( iThisGroup >= iLastSeekAddr || |
|
416 ( iNextGroupPoint >= iLastSeekAddr && |
|
417 iToFile && iToFile->Action() == MRtpFileWriteObserver::ESavePause ) ) |
|
418 { |
|
419 LOG2( "CRtpFromFile::RunL(), All groups readed ! total: %d, iDuration: %d", |
|
420 iThisGroup, iDuration ); |
|
421 iGroupTime = iDuration; |
|
422 } |
|
423 |
|
424 iReadObs.GroupReadedL( iDataPtr, iGroupTime, ( iGroupTime >= iDuration ) ); |
|
425 delete iFileData; iFileData = NULL; |
|
426 } |
|
427 |
|
428 // ----------------------------------------------------------------------------- |
|
429 // CRtpFromFile::RunError |
|
430 // ----------------------------------------------------------------------------- |
|
431 // |
|
432 TInt CRtpFromFile::RunError( TInt aError ) |
|
433 { |
|
434 LOG1( "CRtpFromFile::RunError(), RunL Leaved: %d", aError ); |
|
435 |
|
436 iReadObs.ReadStatus( aError ); |
|
437 StopRtpRead( aError, 0 ); |
|
438 return KErrNone; |
|
439 } |
|
440 |
|
441 // ----------------------------------------------------------------------------- |
|
442 // CRtpFromFile::DoCancel |
|
443 // ----------------------------------------------------------------------------- |
|
444 // |
|
445 void CRtpFromFile::DoCancel() |
|
446 { |
|
447 LOG( "CRtpFromFile::DoCancel()" ); |
|
448 } |
|
449 |
|
450 // ----------------------------------------------------------------------------- |
|
451 // CRtpFromFile::TimerEventL |
|
452 // Internal timer call this when triggered. |
|
453 // ----------------------------------------------------------------------------- |
|
454 // |
|
455 void CRtpFromFile::TimerEventL() |
|
456 { |
|
457 LOG( "CRtpFromFile::TimerEventL() in" ); |
|
458 |
|
459 ReadGroupHeaderL(); |
|
460 ReadNextGroupFromFileL(); |
|
461 delete iTimer; iTimer = NULL; |
|
462 |
|
463 LOG( "CRtpFromFile::TimerEventL() out" ); |
|
464 } |
|
465 |
|
466 // ----------------------------------------------------------------------------- |
|
467 // CRtpFromFile::TimerError |
|
468 // Internal timer call this when TimerEventL() leaves. |
|
469 // ----------------------------------------------------------------------------- |
|
470 // |
|
471 void CRtpFromFile::TimerError( const TInt aError ) |
|
472 { |
|
473 LOG1( "CRtpFromFile::TimerError(), TimerEventL Leaved: %d", aError ); |
|
474 |
|
475 StopRtpRead( aError, 0 ); |
|
476 delete iTimer; iTimer = NULL; |
|
477 } |
|
478 |
|
479 // ----------------------------------------------------------------------------- |
|
480 // CRtpFromFile::ReadClipHeaderL |
|
481 // Reads meta data and seek header from the beginning of the file. |
|
482 // ----------------------------------------------------------------------------- |
|
483 // |
|
484 void CRtpFromFile::ReadClipHeaderL( TInt8& aVersion ) |
|
485 { |
|
486 LOG1( "CRtpFromFile::ReadClipHeaderL(), iToFile: %d", iToFile ); |
|
487 |
|
488 if ( !iToFile ) |
|
489 { |
|
490 TInt seekArrayPoint( KErrNotFound ); |
|
491 aVersion = ReadMetaHeaderL( iSeekHeaderPoint, seekArrayPoint ); |
|
492 ReadSeekHeaderL(); |
|
493 |
|
494 // Read seek array if exist |
|
495 if ( seekArrayPoint > iLastSeekAddr ) |
|
496 { |
|
497 ReadSeekArrayL( seekArrayPoint ); |
|
498 } |
|
499 } |
|
500 else // Recording ongoing with the same clip |
|
501 { |
|
502 aVersion = KCurrentClipVersion; |
|
503 iSeekHeaderPoint = iToFile->SeekHeaderPoint(); |
|
504 iGroupsTotalCount = iToFile->GroupsTotalCount(); |
|
505 iFirstSeekAddr = iToFile->FirstSeekAddr(); |
|
506 iLastSeekAddr = iToFile->LastSeekAddr(); |
|
507 } |
|
508 |
|
509 iNextGroupPoint = iFirstSeekAddr; |
|
510 } |
|
511 |
|
512 // ----------------------------------------------------------------------------- |
|
513 // CRtpFromFile::ReadMetaHeaderL |
|
514 // Reads meta data header from the beginning of the file. |
|
515 // ----------------------------------------------------------------------------- |
|
516 // |
|
517 TInt8 CRtpFromFile::ReadMetaHeaderL( |
|
518 TInt& aSeekHeaderPoint, |
|
519 TInt& aSeekArrayPoint ) |
|
520 { |
|
521 CRtpMetaHeader* metaheader = CRtpMetaHeader::NewLC( |
|
522 iFile, CRtpMetaHeader::EMetaRead ); |
|
523 aSeekHeaderPoint = metaheader->SeekHeaderPoint(); |
|
524 metaheader->ReadSeekArrayPointL( aSeekArrayPoint ); |
|
525 LOG2( "CRtpFromFile::ReadMetaHeaderL(), aSeekHeaderPoint: %d, aSeekArrayPoint: %d", |
|
526 aSeekHeaderPoint, aSeekArrayPoint ); |
|
527 // Clip version |
|
528 CRtpMetaHeader::SAttributes att; |
|
529 metaheader->ReadAttributesL( att ); |
|
530 metaheader->ReadDurationL( iDuration ); |
|
531 |
|
532 // Verify post rule |
|
533 CRtpClipManager* clipManager = CRtpClipManager::NewLC(); |
|
534 clipManager->VerifyPostRuleL( att.iPostRule, metaheader ); |
|
535 CleanupStack::PopAndDestroy( clipManager ); |
|
536 CleanupStack::PopAndDestroy( metaheader ); |
|
537 |
|
538 LOG2( "CRtpFromFile::ReadMetaHeaderL(), Version: %d, Duration: %d", |
|
539 att.iVersion, iDuration ); |
|
540 return att.iVersion; |
|
541 } |
|
542 |
|
543 // ----------------------------------------------------------------------------- |
|
544 // CRtpFromFile::ReadNextGroupFromFileL |
|
545 // Reads RTP payload from a file. |
|
546 // Payload is allways after data header, so read position set is not needed. |
|
547 // ----------------------------------------------------------------------------- |
|
548 // |
|
549 void CRtpFromFile::ReadNextGroupFromFileL() |
|
550 { |
|
551 LOG2( "CRtpFromFile::ReadNextGroupFromFileL(), iThisGroup: %d, iGroupTime: %u", |
|
552 iThisGroup, iGroupTime ); |
|
553 #ifdef CR_ALL_LOGS |
|
554 LogVariables( _L( "ReadNextGroupFromFileL()" ) ); |
|
555 #endif // CR_ALL_LOGS |
|
556 |
|
557 const TInt len( iGroupTotalLen - KGroupHeaderBytes ); |
|
558 if ( len <= 0 || iThisGroup < iFirstSeekAddr || iThisGroup > iLastSeekAddr ) |
|
559 { |
|
560 #ifdef CR_ALL_LOGS |
|
561 LogVariables( _L( "ReadNextGroupFromFileL()" ) ); |
|
562 #endif // CR_ALL_LOGS |
|
563 |
|
564 LOG( "CRtpFromFile::ReadNextGroupFromFileL(), No More Groups" ); |
|
565 User::Leave( KErrEof ); |
|
566 } |
|
567 |
|
568 // Reading should never be active at this point |
|
569 if ( iFileData != NULL ) |
|
570 { |
|
571 LOG( "CRtpFromFile::ReadNextGroupFromFileL(), Invalid usage of class !" ); |
|
572 User::Leave( KErrGeneral ); |
|
573 } |
|
574 |
|
575 // Start reading group |
|
576 iFileData = HBufC8::NewL( len ); |
|
577 iDataPtr.Set( iFileData->Des() ); |
|
578 iFile.Read( iThisGroup + KGroupHeaderBytes, iDataPtr, len, iStatus ); |
|
579 SetActive(); |
|
580 } |
|
581 |
|
582 // ----------------------------------------------------------------------------- |
|
583 // CRtpFromFile::FindSeekGroup |
|
584 // Finds closes point with seek array, accuracy about 0 - 30 s. |
|
585 // ----------------------------------------------------------------------------- |
|
586 // |
|
587 TInt CRtpFromFile::FindSeekGroup( const TUint aTime, CArrayFix<SSeek>* aArray ) |
|
588 { |
|
589 if ( aArray->Count() && aTime >= aArray->At( 0 ).iTime ) |
|
590 { |
|
591 for ( TInt i( aArray->Count() - 1 ); i > 0 ; i-- ) |
|
592 { |
|
593 #ifdef CR_ALL_LOGS |
|
594 LOG3( "CRtpFromFile::FindSeekGroup(), ind: %d, aTime: %u, array time: %u", |
|
595 i, aTime, aArray->At( i ).iTime ); |
|
596 #endif //CR_ALL_LOGS |
|
597 |
|
598 if ( aTime > aArray->At( i ).iTime ) |
|
599 { |
|
600 return aArray->At( i ).iPoint; |
|
601 } |
|
602 } |
|
603 |
|
604 return aArray->At( 0 ).iPoint; |
|
605 } |
|
606 |
|
607 return KErrNotFound; |
|
608 } |
|
609 |
|
610 // ----------------------------------------------------------------------------- |
|
611 // CRtpFromFile::UpdatePlayAttL |
|
612 // Updates clip's playback count and spot attributes after watching. |
|
613 // ----------------------------------------------------------------------------- |
|
614 // |
|
615 void CRtpFromFile::UpdatePlayAttL() |
|
616 { |
|
617 // Update attributes |
|
618 if ( iMode == EModeNormal ) |
|
619 { |
|
620 iFile.Close(); |
|
621 User::LeaveIfError( iFile.Open( iFs, *iCurrentPath, |
|
622 EFileShareAny | EFileStream | EFileWrite ) ); |
|
623 } |
|
624 |
|
625 CRtpMetaHeader* metaheader = CRtpMetaHeader::NewLC( |
|
626 iFile, CRtpMetaHeader::EMetaUpdate ); |
|
627 TTime startTime( 0 ); |
|
628 metaheader->ReadStartTimeL( startTime ); |
|
629 |
|
630 CRtpMetaHeader::SAttributes att; |
|
631 metaheader->ReadAttributesL( att ); |
|
632 |
|
633 // Step playback counter by one |
|
634 att.iPlayCount++; |
|
635 // Update play spot |
|
636 att.iPlaySpot = ( iThisGroup > 0 && iThisGroup < iLastSeekAddr )? iThisGroup: |
|
637 KErrNone; |
|
638 metaheader->WriteAttributesL( att ); |
|
639 CleanupStack::PopAndDestroy( metaheader ); |
|
640 LOG2( "CRtpFromFile::UpdatePlayAttL(), New play count: %d, spot: %d", |
|
641 att.iPlayCount, att.iPlaySpot ); |
|
642 // Set start time to file date |
|
643 iFile.SetModified( startTime ); |
|
644 } |
|
645 |
|
646 // ----------------------------------------------------------------------------- |
|
647 // CRtpFromFile::LastSeekAddr |
|
648 // Gets last seek addres. |
|
649 // It is either from opened clip or from file writer when recording is ongoing. |
|
650 // ----------------------------------------------------------------------------- |
|
651 // |
|
652 TInt CRtpFromFile::LastSeekAddr() |
|
653 { |
|
654 if ( iToFile ) |
|
655 { |
|
656 iLastSeekAddr = iToFile->LastSeekAddr(); |
|
657 } |
|
658 |
|
659 return iLastSeekAddr; |
|
660 } |
|
661 |
|
662 // End of File |
|
663 |