|
1 /* |
|
2 * Copyright (c) 2006 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: TNE Video Clip Implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 #include "TNEVideoClipInfoImp.h" |
|
22 #include "TNEProcessor.h" |
|
23 #include <fbs.h> |
|
24 #include <coemain.h> |
|
25 #include <ecom/ecom.h> |
|
26 |
|
27 // Print macro |
|
28 #ifdef _DEBUG |
|
29 #include <e32svr.h> |
|
30 #define PRINT(x) RDebug::Print x |
|
31 #else |
|
32 #define PRINT(x) |
|
33 #endif |
|
34 |
|
35 |
|
36 // ----------------------------------------------------------------------------- |
|
37 // CTNEVideoClipInfo::NewL |
|
38 // API exposed by TNE to create TNEVideoClipInfo using RFile handle |
|
39 // ----------------------------------------------------------------------------- |
|
40 EXPORT_C CTNEVideoClipInfo* CTNEVideoClipInfo::NewL(const RFile& aFileHandle, |
|
41 MTNEVideoClipInfoObserver& aObserver) |
|
42 { |
|
43 PRINT(_L("CTNEVideoClipInfo::NewL")); |
|
44 |
|
45 CTNEVideoClipInfoImp* self = (CTNEVideoClipInfoImp*)NewLC(aFileHandle, aObserver); |
|
46 CleanupStack::Pop(self); |
|
47 |
|
48 PRINT(_L("CTNEVideoClipInfo::NewL out")); |
|
49 return self; |
|
50 } |
|
51 |
|
52 // ----------------------------------------------------------------------------- |
|
53 // CTNEVideoClipInfo::NewL |
|
54 // API exposed by TNE to create TNEVideoClipInfo using file name |
|
55 // ----------------------------------------------------------------------------- |
|
56 EXPORT_C CTNEVideoClipInfo* CTNEVideoClipInfo::NewL(const TDesC& aFileName, |
|
57 MTNEVideoClipInfoObserver& aObserver) |
|
58 { |
|
59 PRINT(_L("CTNEVideoClipInfo::NewL")); |
|
60 |
|
61 CTNEVideoClipInfoImp* self = (CTNEVideoClipInfoImp*)NewLC(aFileName, aObserver); |
|
62 CleanupStack::Pop(self); |
|
63 |
|
64 PRINT(_L("CTNEVideoClipInfo::NewL out")); |
|
65 return self; |
|
66 } |
|
67 |
|
68 EXPORT_C CTNEVideoClipInfo* CTNEVideoClipInfo::NewLC(const RFile& aFileHandle, |
|
69 MTNEVideoClipInfoObserver& aObserver) |
|
70 { |
|
71 PRINT(_L("CTNEVideoClipInfo::NewLC in")); |
|
72 |
|
73 CTNEVideoClipInfoImp* self = new (ELeave) CTNEVideoClipInfoImp(); |
|
74 CleanupStack::PushL(self); |
|
75 self->ConstructL(aFileHandle, aObserver); |
|
76 |
|
77 PRINT(_L("CTNEVideoClipInfo::NewLC out")); |
|
78 return self; |
|
79 } |
|
80 |
|
81 EXPORT_C CTNEVideoClipInfo* CTNEVideoClipInfo::NewLC(const TDesC& aFileName, |
|
82 MTNEVideoClipInfoObserver& aObserver) |
|
83 { |
|
84 PRINT(_L("CTNEVideoClipInfo::NewLC in")); |
|
85 |
|
86 CTNEVideoClipInfoImp* self = new (ELeave) CTNEVideoClipInfoImp(); |
|
87 CleanupStack::PushL(self); |
|
88 self->ConstructL(aFileName, aObserver); |
|
89 |
|
90 PRINT(_L("CTNEVideoClipInfo::NewLC out")); |
|
91 return self; |
|
92 } |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 CTNEVideoClipInfo* CTNEVideoClipInfoImp::NewL(const RFile& aFileHandle, |
|
98 MTNEVideoClipInfoObserver& aObserver) |
|
99 { |
|
100 CTNEVideoClipInfoImp* self = new (ELeave) CTNEVideoClipInfoImp(); |
|
101 CleanupStack::PushL(self); |
|
102 self->ConstructL(aFileHandle, aObserver); |
|
103 CleanupStack::Pop(self); |
|
104 return self; |
|
105 } |
|
106 |
|
107 CTNEVideoClipInfoImp::CTNEVideoClipInfoImp() |
|
108 : iReady(EFalse) |
|
109 { |
|
110 iFs = NULL; |
|
111 } |
|
112 |
|
113 |
|
114 TInt CTNEVideoClipInfoImp::VideoFrameCount() const |
|
115 { |
|
116 __ASSERT_ALWAYS(iReady, |
|
117 TTNEPanic::Panic(TTNEPanic::EVideoClipInfoNotReady)); |
|
118 |
|
119 return iVideoFrameCount; |
|
120 } |
|
121 |
|
122 |
|
123 void CTNEVideoClipInfoImp::ConstructL(const RFile& aFileHandle, |
|
124 MTNEVideoClipInfoObserver& aObserver) |
|
125 { |
|
126 PRINT(_L("CTNEVideoClipInfo::ConstructL in")); |
|
127 |
|
128 iFileHandle.Duplicate(aFileHandle); |
|
129 |
|
130 iThumbOperation = CTNEVideoClipThumbOperation::NewL(this); |
|
131 |
|
132 iInfoOperation = CTNEVideoClipInfoOperation::NewL(this, aObserver); |
|
133 |
|
134 PRINT(_L("CTNEVideoClipInfo::ConstructL out")); |
|
135 } |
|
136 |
|
137 void CTNEVideoClipInfoImp::ConstructL(const TDesC& aFileName, |
|
138 MTNEVideoClipInfoObserver& aObserver) |
|
139 { |
|
140 PRINT(_L("CTNEVideoClipInfo::ConstructL in")); |
|
141 |
|
142 // Get RFile Handle |
|
143 iFs = new (ELeave) RFs; |
|
144 User::LeaveIfError(iFs->Connect()); |
|
145 |
|
146 TInt iError = iFileHandle.Open(*iFs, aFileName, EFileShareReadersOnly | EFileStream | EFileRead); |
|
147 |
|
148 iThumbOperation = CTNEVideoClipThumbOperation::NewL(this); |
|
149 |
|
150 iInfoOperation = CTNEVideoClipInfoOperation::NewL(this, aObserver); |
|
151 |
|
152 PRINT(_L("CTNEVideoClipInfo::ConstructL out")); |
|
153 } |
|
154 |
|
155 |
|
156 CTNEVideoClipInfoImp::~CTNEVideoClipInfoImp() |
|
157 { |
|
158 PRINT(_L("CTNEVideoClipInfo::~CTNEVideoClipInfoImp in")); |
|
159 |
|
160 delete iInfoOperation; |
|
161 delete iThumbOperation; |
|
162 |
|
163 iFileHandle.Close(); |
|
164 |
|
165 if(iFs) |
|
166 { |
|
167 iFs->Close(); |
|
168 delete iFs; |
|
169 } |
|
170 |
|
171 REComSession::FinalClose(); |
|
172 |
|
173 PRINT(_L("CTNEVideoClipInfo::~CTNEVideoClipInfoImp out")); |
|
174 } |
|
175 |
|
176 |
|
177 void CTNEVideoClipInfoImp::GetThumbL(MTNEVideoClipThumbObserver& aObserver, |
|
178 TInt aIndex, |
|
179 TSize* const aResolution, |
|
180 TDisplayMode aDisplayMode, |
|
181 TBool aEnhance, |
|
182 TInt aPriority) |
|
183 { |
|
184 PRINT(_L("CTNEVideoClipInfoImp::GetThumbL in")); |
|
185 |
|
186 __ASSERT_ALWAYS(iReady, |
|
187 TTNEPanic::Panic(TTNEPanic::EVideoClipInfoNotReady)); |
|
188 |
|
189 iThumbOperation->StartL(aObserver, aIndex, aResolution, aDisplayMode, aEnhance, aPriority); |
|
190 |
|
191 PRINT(_L("CTNEVideoClipInfoImp::GetThumbL out")); |
|
192 } |
|
193 |
|
194 |
|
195 void CTNEVideoClipInfoImp::CancelThumb() |
|
196 { |
|
197 PRINT(_L("CTNEVideoClipInfoImp::CancelThumb in")); |
|
198 |
|
199 if ( !iReady ) |
|
200 { |
|
201 PRINT(_L("CTNEVideoClipInfoImp::CancelThumb not even info ready yet, cancel it and get out")); |
|
202 iInfoOperation->Cancel(); |
|
203 return; |
|
204 } |
|
205 |
|
206 iThumbOperation->Cancel(); |
|
207 |
|
208 PRINT(_L("CTNEVideoClipInfoImp::CancelThumb out")); |
|
209 } |
|
210 |
|
211 |
|
212 TPtrC CTNEVideoClipInfoImp::FileName() const |
|
213 { |
|
214 __ASSERT_ALWAYS(iReady, |
|
215 TTNEPanic::Panic(TTNEPanic::EVideoClipInfoNotReady)); |
|
216 |
|
217 TFileName fileName; |
|
218 iFileHandle.FullName(fileName); |
|
219 |
|
220 return fileName; |
|
221 } |
|
222 |
|
223 |
|
224 TSize CTNEVideoClipInfoImp::GetResolution() const |
|
225 { |
|
226 __ASSERT_ALWAYS(iReady, |
|
227 TTNEPanic::Panic(TTNEPanic::EVideoClipInfoNotReady)); |
|
228 |
|
229 return iResolution; |
|
230 } |
|
231 |
|
232 /********************************************** |
|
233 *** Video Clip Info Operations ** |
|
234 *** ** |
|
235 **********************************************/ |
|
236 |
|
237 CTNEVideoClipInfoOperation* CTNEVideoClipInfoOperation::NewL(CTNEVideoClipInfoImp* aInfo, |
|
238 MTNEVideoClipInfoObserver& aObserver) |
|
239 { |
|
240 PRINT(_L("CTNEVideoClipInfoOperation::NewL in")); |
|
241 |
|
242 CTNEVideoClipInfoOperation* self = |
|
243 new (ELeave) CTNEVideoClipInfoOperation(aInfo, aObserver); |
|
244 CleanupStack::PushL(self); |
|
245 self->ConstructL(); |
|
246 CleanupStack::Pop(self); |
|
247 |
|
248 PRINT(_L("CTNEVideoClipInfoOperation::NewL out")); |
|
249 return self; |
|
250 } |
|
251 |
|
252 |
|
253 CTNEVideoClipInfoOperation::CTNEVideoClipInfoOperation(CTNEVideoClipInfoImp* aInfo, |
|
254 MTNEVideoClipInfoObserver& aObserver) |
|
255 : CActive(EPriorityStandard), iInfo(aInfo), iTNEProcessorError(KErrNone) |
|
256 { |
|
257 PRINT(_L("CTNEVideoClipInfoOperation::CTNEVideoClipInfoOperation in")); |
|
258 |
|
259 iObserver = &aObserver; |
|
260 CActiveScheduler::Add(this); |
|
261 |
|
262 PRINT(_L("CTNEVideoClipInfoOperation::CTNEVideoClipInfoOperation out")); |
|
263 } |
|
264 |
|
265 |
|
266 void CTNEVideoClipInfoOperation::ConstructL() |
|
267 { |
|
268 PRINT(_L("CTNEVideoClipInfoOperation::ConstructL in")); |
|
269 |
|
270 CTNEProcessor* processor = CTNEProcessor::NewL(); |
|
271 TRAP(iTNEProcessorError, |
|
272 processor->GetVideoClipPropertiesL((iInfo->iFileHandle), |
|
273 iInfo->iFormat, |
|
274 iInfo->iVideoType, |
|
275 iInfo->iResolution, |
|
276 iInfo->iVideoFrameCount |
|
277 )); |
|
278 delete processor; |
|
279 processor = 0; |
|
280 |
|
281 PRINT((_L("CTNEVideoClipInfoOperation::ConstructL GetVideoClipInfo returned: %d "), iTNEProcessorError )); |
|
282 |
|
283 if ((iTNEProcessorError == KErrNone) |
|
284 || (iTNEProcessorError == KErrNotFound) |
|
285 || (iTNEProcessorError == KErrPathNotFound) |
|
286 || (iTNEProcessorError == KErrNotSupported)) |
|
287 { |
|
288 // Report also certain common error conditions to the observer instead of leaving |
|
289 SetActive(); |
|
290 TRequestStatus* status = &iStatus; |
|
291 User::RequestComplete(status, KErrNone); |
|
292 } |
|
293 else |
|
294 { |
|
295 User::Leave(iTNEProcessorError); |
|
296 } |
|
297 |
|
298 PRINT(_L("CTNEVideoClipInfoOperation::ConstructL out")); |
|
299 } |
|
300 |
|
301 |
|
302 CTNEVideoClipInfoOperation::~CTNEVideoClipInfoOperation() |
|
303 { |
|
304 Cancel(); |
|
305 } |
|
306 |
|
307 void CTNEVideoClipInfoOperation::RunL() |
|
308 { |
|
309 PRINT(_L("CTNEVideoClipInfoOperation::RunL in")); |
|
310 |
|
311 if (iTNEProcessorError != KErrNone) |
|
312 { |
|
313 iObserver->NotifyVideoClipInfoReady(*iInfo, iTNEProcessorError); |
|
314 } |
|
315 else |
|
316 { |
|
317 if (iTNEProcessorError == KErrNone) |
|
318 { |
|
319 iInfo->iReady = ETrue; |
|
320 } |
|
321 iObserver->NotifyVideoClipInfoReady(*iInfo, iTNEProcessorError); |
|
322 } |
|
323 |
|
324 PRINT(_L("CTNEVideoClipInfoOperation::RunL out")); |
|
325 } |
|
326 |
|
327 |
|
328 // *********************************************************************** |
|
329 // This function gets called by the Cancel operation of the Active object. |
|
330 // Standard implementation of the cancel operation on a active object |
|
331 // *********************************************************************** |
|
332 |
|
333 void CTNEVideoClipInfoOperation::DoCancel() |
|
334 { |
|
335 } |
|
336 |
|
337 |
|
338 |
|
339 /********************************** |
|
340 *** Thumb Operations ** |
|
341 *** ** |
|
342 ***********************************/ |
|
343 |
|
344 CTNEVideoClipThumbOperation* CTNEVideoClipThumbOperation::NewL(CTNEVideoClipInfoImp* aInfo) |
|
345 { |
|
346 PRINT(_L("CTNEVideoClipThumbOperation::NewL in")); |
|
347 |
|
348 CTNEVideoClipThumbOperation* self = |
|
349 new (ELeave) CTNEVideoClipThumbOperation(aInfo); |
|
350 |
|
351 CleanupStack::PushL(self); |
|
352 self->ConstructL(); |
|
353 CleanupStack::Pop(self); |
|
354 |
|
355 PRINT(_L("CTNEVideoClipThumbOperation::NewL out")); |
|
356 return self; |
|
357 } |
|
358 |
|
359 |
|
360 CTNEVideoClipThumbOperation::CTNEVideoClipThumbOperation(CTNEVideoClipInfoImp* aInfo) |
|
361 : CActive(EPriorityIdle), iInfo(aInfo) |
|
362 { |
|
363 PRINT(_L("CTNEVideoClipThumbOperation::CTNEVideoClipThumbOperation in")); |
|
364 CActiveScheduler::Add(this); |
|
365 PRINT(_L("CTNEVideoClipThumbOperation::CTNEVideoClipThumbOperation out")); |
|
366 } |
|
367 |
|
368 |
|
369 void CTNEVideoClipThumbOperation::ConstructL() |
|
370 { |
|
371 } |
|
372 |
|
373 |
|
374 CTNEVideoClipThumbOperation::~CTNEVideoClipThumbOperation() |
|
375 { |
|
376 Cancel(); |
|
377 } |
|
378 |
|
379 |
|
380 void CTNEVideoClipThumbOperation::StartL(MTNEVideoClipThumbObserver& aObserver, |
|
381 TInt aIndex, |
|
382 TSize* const aResolution, |
|
383 TDisplayMode aDisplayMode, |
|
384 TBool aEnhance, |
|
385 TInt aPriority) |
|
386 { |
|
387 PRINT(_L("CTNEVideoClipThumbOperation::StartL in")); |
|
388 |
|
389 __ASSERT_ALWAYS(!IsActive(), |
|
390 TTNEPanic::Panic(TTNEPanic::EVideoClipInfoFrameOperationAlreadyRunning)); |
|
391 __ASSERT_DEBUG(iTNEProcessor == 0, TTNEPanic::Panic(TTNEPanic::EInternal)); |
|
392 |
|
393 TSize resolution; |
|
394 if (aResolution != 0) |
|
395 { |
|
396 __ASSERT_ALWAYS(aResolution->iWidth >= 0, |
|
397 TTNEPanic::Panic(TTNEPanic::EVideoClipInfoIllegalFrameResolution)); |
|
398 __ASSERT_ALWAYS(aResolution->iHeight >= 0, |
|
399 TTNEPanic::Panic(TTNEPanic::EVideoClipInfoIllegalFrameResolution)); |
|
400 |
|
401 resolution = *aResolution; |
|
402 } |
|
403 else |
|
404 { |
|
405 resolution = iInfo->GetResolution(); |
|
406 // need check here to see if resolution retreived from the clip is bad |
|
407 if ((resolution.iHeight <=0) || (resolution.iWidth <=0 )) |
|
408 { |
|
409 resolution.iHeight = 96; |
|
410 resolution.iWidth = 128; |
|
411 } |
|
412 } |
|
413 |
|
414 // Verify that IndexFrame is within limit |
|
415 __ASSERT_ALWAYS(((aIndex >= 0) && (iInfo->VideoFrameCount() == 0) || |
|
416 (aIndex < iInfo->VideoFrameCount()) || |
|
417 (aIndex == KBestThumbIndex) ), |
|
418 TTNEPanic::Panic(TTNEPanic::EVideoClipInfoIllegalVideoFrameIndex)); |
|
419 |
|
420 iIndex = aIndex; |
|
421 |
|
422 CTNEProcessor* processor = CTNEProcessor::NewLC(); |
|
423 processor->StartThumbL((iInfo->iFileHandle), aIndex, resolution, aDisplayMode, |
|
424 aEnhance); |
|
425 |
|
426 /* Initialization OK. This method cannot leave any more. Start processing. */ |
|
427 |
|
428 CleanupStack::Pop(processor); |
|
429 |
|
430 iTNEProcessor = processor; |
|
431 iObserver = &aObserver; |
|
432 |
|
433 SetPriority(aPriority); |
|
434 SetActive(); |
|
435 TRequestStatus* status = &iStatus; |
|
436 User::RequestComplete(status, KErrNone); |
|
437 |
|
438 PRINT(_L("CTNEVideoClipThumbOperation::StartL out")); |
|
439 } |
|
440 |
|
441 |
|
442 void CTNEVideoClipThumbOperation::RunL() |
|
443 { |
|
444 PRINT(_L("CTNEVideoClipThumbOperation::RunL in")); |
|
445 |
|
446 __ASSERT_DEBUG(iTNEProcessor != 0, TTNEPanic::Panic(TTNEPanic::EInternal)); |
|
447 __ASSERT_DEBUG(iObserver != 0, TTNEPanic::Panic(TTNEPanic::EInternal)); |
|
448 |
|
449 TInt err = KErrNone; |
|
450 |
|
451 if (!iThumbRequestPending) |
|
452 TRAP(err, iTNEProcessor->ProcessThumbL(iStatus)); |
|
453 |
|
454 if (err != KErrNone) |
|
455 { |
|
456 delete iTNEProcessor; |
|
457 iTNEProcessor = 0; |
|
458 |
|
459 MTNEVideoClipThumbObserver* observer = iObserver; |
|
460 iObserver = 0; |
|
461 observer->NotifyVideoClipThumbCompleted(*iInfo, err, NULL); |
|
462 return; |
|
463 } |
|
464 |
|
465 // the control flows to ih263 decoder |
|
466 // in the next loop it gets to this runl again |
|
467 if (!iThumbRequestPending) |
|
468 { |
|
469 iThumbRequestPending = ETrue; |
|
470 iStatus = KRequestPending; |
|
471 SetActive(); |
|
472 return; |
|
473 } |
|
474 else |
|
475 { |
|
476 MTNEVideoClipThumbObserver* observer = iObserver; |
|
477 iObserver = 0; |
|
478 |
|
479 if (iStatus == KErrNone) |
|
480 { |
|
481 CFbsBitmap* frame = 0; |
|
482 iTNEProcessor->FetchThumb(frame); |
|
483 observer->NotifyVideoClipThumbCompleted(*iInfo, KErrNone, frame); |
|
484 } |
|
485 else |
|
486 { |
|
487 observer->NotifyVideoClipThumbCompleted(*iInfo, iStatus.Int(), NULL); |
|
488 } |
|
489 iThumbRequestPending = EFalse; |
|
490 delete iTNEProcessor; |
|
491 iTNEProcessor = 0; |
|
492 } |
|
493 |
|
494 PRINT(_L("CTNEVideoClipThumbOperation::RunL out")); |
|
495 } |
|
496 |
|
497 |
|
498 void CTNEVideoClipThumbOperation::DoCancel() |
|
499 { |
|
500 if (iTNEProcessor != 0) |
|
501 { |
|
502 delete iTNEProcessor; |
|
503 iTNEProcessor = 0; |
|
504 |
|
505 // Cancel our internal request |
|
506 if ( iStatus == KRequestPending ) |
|
507 { |
|
508 PRINT((_L("CTNEVideoClipThumbOperation::DoCancel() cancel request"))); |
|
509 TRequestStatus *status = &iStatus; |
|
510 User::RequestComplete(status, KErrCancel); |
|
511 } |
|
512 |
|
513 MTNEVideoClipThumbObserver* observer = iObserver; |
|
514 iObserver = 0; |
|
515 observer->NotifyVideoClipThumbCompleted(*iInfo, KErrCancel, NULL); |
|
516 } |
|
517 } |
|
518 |