|
1 /* |
|
2 * Copyright (c) 2010 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: |
|
15 * Source file for the main class of the Thumbnail Tester test app. |
|
16 * |
|
17 */ |
|
18 |
|
19 #include "thumbnailtester.h" |
|
20 #include "yuv2rgb24.h" |
|
21 |
|
22 #include <e32base.h> |
|
23 #include <e32debug.h> |
|
24 #include <f32file.h> |
|
25 |
|
26 const TInt KFontSize = 15; |
|
27 |
|
28 // Thumbnail tester implementation |
|
29 |
|
30 void CThumbnailTester::ExecuteL() |
|
31 { |
|
32 CThumbnailTester* self = new(ELeave) CThumbnailTester; |
|
33 CleanupStack::PushL( self ); |
|
34 self->InitL(); |
|
35 self->Main(); |
|
36 CleanupStack::PopAndDestroy( self ); |
|
37 } |
|
38 |
|
39 CThumbnailTester::CThumbnailTester() : |
|
40 CTestAppBase( KFontSize ) |
|
41 { |
|
42 } |
|
43 |
|
44 CThumbnailTester::~CThumbnailTester() |
|
45 { |
|
46 Cancel(); |
|
47 |
|
48 if( iGc && iFullScreenWindow ) |
|
49 { |
|
50 iGc->Activate(*iFullScreenWindow); |
|
51 |
|
52 iFullScreenWindow->Invalidate(); |
|
53 iFullScreenWindow->BeginRedraw(); |
|
54 |
|
55 iGc->Reset(); |
|
56 |
|
57 iGc->UseFont(iFont); |
|
58 iGc->SetBrushColor(KRgbDarkBlue); |
|
59 |
|
60 iGc->Clear(); |
|
61 |
|
62 if( iFinalResult == KErrNone ) |
|
63 { |
|
64 // KRgbWhite seems to be having problems (0xffffff) in some emulators, |
|
65 // but 0xfefefe is working, so use that instead of white. |
|
66 iGc->SetPenColor(0xfefefe); |
|
67 } |
|
68 else |
|
69 { |
|
70 iGc->SetPenColor(KRgbRed); |
|
71 } |
|
72 |
|
73 iBuffer.Format( _L("THUMBNAILTESTER EXIT, result = %i"), iFinalResult ); |
|
74 iGc->DrawText( iBuffer, TPoint(5, 20) ); |
|
75 |
|
76 iFullScreenWindow->EndRedraw(); |
|
77 |
|
78 iGc->Deactivate(); |
|
79 |
|
80 iFullScreenWindow->SetVisible( ETrue ); |
|
81 |
|
82 WaitForAnyKey(); |
|
83 } |
|
84 |
|
85 } |
|
86 |
|
87 void CThumbnailTester::InitL() |
|
88 { |
|
89 BaseConstructL( NULL, 0 ); // this app doesn't use the option pages concept |
|
90 |
|
91 iFullScreenWindow = new(ELeave) RWindow( iWs ); |
|
92 User::LeaveIfError( iFullScreenWindow->Construct( *iWindowGroup, KNullWsHandle ) ); |
|
93 iFullScreenWindow->SetExtent( TPoint(0,0), iDisplaySize ); |
|
94 iFullScreenWindow->SetNonTransparent(); |
|
95 iFullScreenWindow->SetBackgroundColor(KRgbBlack); |
|
96 iFullScreenWindow->SetVisible(false); |
|
97 iFullScreenWindow->Activate(); |
|
98 |
|
99 iGc->Activate(*iFullScreenWindow); |
|
100 |
|
101 iFullScreenWindow->BeginRedraw(); |
|
102 |
|
103 iGc->Reset(); |
|
104 iGc->UseFont(iFont); |
|
105 iGc->SetBrushStyle(CWindowGc::ESolidBrush); |
|
106 iGc->SetBrushColor(KRgbBlack); |
|
107 iGc->Clear(); |
|
108 |
|
109 iFullScreenWindow->EndRedraw(); |
|
110 |
|
111 iGc->Deactivate(); |
|
112 } |
|
113 |
|
114 void CThumbnailTester::Main() |
|
115 { |
|
116 TRAPD( err, MainL() ); |
|
117 |
|
118 RDebug::Printf( "THUMBNAILTESTER Completed, err=%i", err ); |
|
119 } |
|
120 |
|
121 void CThumbnailTester::MainL() |
|
122 { |
|
123 TFileName filename; |
|
124 |
|
125 SelectFileWithHistoryL( TPoint(0,0), iDisplaySize, filename, KHistoryFilename, KMaxHistoryEntries ); |
|
126 |
|
127 GenerateThumbnailL( filename ); |
|
128 } |
|
129 |
|
130 void CThumbnailTester::GenerateThumbnailL( TDes& aFileName ) |
|
131 { |
|
132 SelectIntegerL( TPoint(0,0), iDisplaySize, _L("Select starting position(seconds):"), 0, 9999, iStartPositionInMs ); |
|
133 |
|
134 // Convert from seconds to ms. |
|
135 iStartPositionInMs *= 1000; |
|
136 |
|
137 _LIT( KFull, "Full speed" ); |
|
138 _LIT( KMedium, "100 millisecond delay" ); |
|
139 _LIT( KSlow, "1 second delay" ); |
|
140 |
|
141 RPointerArray<TDesC> speed; |
|
142 speed.Append( &KFull ); |
|
143 speed.Append( &KMedium ); |
|
144 speed.Append( &KSlow ); |
|
145 |
|
146 TInt index = SelectFromListL( TPoint(0,0), iDisplaySize, _L("Select speed:"), speed ); |
|
147 |
|
148 speed.Reset(); |
|
149 |
|
150 switch( index ) |
|
151 { |
|
152 case 0: |
|
153 iDelayBetweenFrames = 0; |
|
154 break; |
|
155 case 1: |
|
156 iDelayBetweenFrames = 100000; // 1/10 second |
|
157 break; |
|
158 case 2: |
|
159 iDelayBetweenFrames = 1000000; // 1 second |
|
160 break; |
|
161 } |
|
162 |
|
163 RFile file; |
|
164 User::LeaveIfError( file.Open( iFs, aFileName, EFileShareReadersOnly | EFileStream | EFileRead ) ); |
|
165 |
|
166 iThumbnailUtility = CHXThumbnailUtility::NewL(*this); |
|
167 |
|
168 bool done = false; |
|
169 |
|
170 iStopThumbnailGeneration = false; |
|
171 |
|
172 StartMonitoringWindowEvents(); |
|
173 |
|
174 TInt originalStartPositionInMs = iStartPositionInMs; |
|
175 |
|
176 while( !done ) |
|
177 { |
|
178 iThumbnailUtility->OpenFileL( file, iStartPositionInMs ); |
|
179 |
|
180 // OpenFileL will block until all bitmaps have been passed to PacketReady. |
|
181 |
|
182 // This isn't necessarily exact, but advance the start position by the time represented |
|
183 // by the number of renderered frames. |
|
184 iStartPositionInMs = originalStartPositionInMs + (iTotalFramesRendered * 1000) / iFrameRateInSec; |
|
185 |
|
186 done = ((iFramesRendered < 5) || iStopThumbnailGeneration); |
|
187 |
|
188 iFramesRendered = 0; |
|
189 } |
|
190 |
|
191 Cancel(); |
|
192 |
|
193 WaitForAnyKey(); |
|
194 |
|
195 delete iThumbnailUtility; |
|
196 iThumbnailUtility = NULL; |
|
197 |
|
198 file.Close(); |
|
199 } |
|
200 |
|
201 bool CThumbnailTester::ConsumeKeyEvent( TInt /*aKeyCode*/ ) |
|
202 { |
|
203 // Stop thumbnail generation when a key is pressed. |
|
204 iStopThumbnailGeneration = true; |
|
205 iThumbnailUtility->CancelThumb(); |
|
206 return true; |
|
207 } |
|
208 |
|
209 void CThumbnailTester::ExecuteOperation( TInt aOperation, const TDesC& aOperationText ) |
|
210 { |
|
211 } |
|
212 |
|
213 void CThumbnailTester::MetaDataReady(TInt aError) |
|
214 { |
|
215 RDebug::Printf( "THUMBNAILTESTER MetadataReady(%i)", aError ); |
|
216 |
|
217 // Get basic meta data. |
|
218 |
|
219 TUint lCount = 0; |
|
220 TUint i=0; |
|
221 |
|
222 iThumbnailUtility->GetMetaDataCount(lCount); |
|
223 |
|
224 RDebug::Printf( "THUMBNAILTESTER metadata count=%i", lCount ); |
|
225 |
|
226 for (i=0; i<lCount; i++) |
|
227 { |
|
228 HBufC *pDes = NULL; |
|
229 HXMetaDataKeys::EHXMetaDataId id; |
|
230 iThumbnailUtility->GetMetaDataAt(i, id, pDes); |
|
231 |
|
232 const char* key = ""; |
|
233 |
|
234 for( TInt j = 0; j < sizeof(HXMetaDataKeyTab)/sizeof(HXMetaDataKeys); j++ ) |
|
235 { |
|
236 if( id == HXMetaDataKeyTab[j].m_id ) |
|
237 { |
|
238 key = HXMetaDataKeyTab[j].m_pHXKey; |
|
239 } |
|
240 } |
|
241 |
|
242 for( TInt j = 0; j < sizeof(HXStreamMetaDataKeyTab)/sizeof(HXMetaDataKeys); j++ ) |
|
243 { |
|
244 if( id == HXStreamMetaDataKeyTab[j].m_id ) |
|
245 { |
|
246 key = HXStreamMetaDataKeyTab[j].m_pHXKey; |
|
247 } |
|
248 } |
|
249 |
|
250 RDebug::Printf( "THUMBNAILTESTER metadata[%i] id=%i key=%s", i, id, key ); |
|
251 |
|
252 TInt current = 0; |
|
253 TBuf8<400> outputLine; |
|
254 while( current < pDes->Length() ) |
|
255 { |
|
256 char c = pDes->Des()[current]; |
|
257 char c2 = c; |
|
258 if( c2 < ' ' || c2 > '~' ) |
|
259 { |
|
260 c2 = ' '; |
|
261 } |
|
262 |
|
263 outputLine.AppendFormat(_L8("%02x/%c "), c, c2 ); |
|
264 |
|
265 current++; |
|
266 |
|
267 if( (current % 20 == 0) || current == pDes->Length() ) |
|
268 { |
|
269 outputLine.Append( '\0' ); |
|
270 RDebug::Printf( (char*)outputLine.Ptr() ); |
|
271 outputLine.SetLength(0); |
|
272 } |
|
273 } |
|
274 |
|
275 if (id == HXMetaDataKeys::EHXFrameSize && pDes) |
|
276 { |
|
277 TPtr pFrameSizePtr = pDes->Des(); |
|
278 _LIT(KChar_x, "x"); |
|
279 TInt xLoc = pFrameSizePtr.Find(KChar_x); |
|
280 if (xLoc != KErrNotFound) |
|
281 { |
|
282 TLex lexWidth(pFrameSizePtr.Mid(0, xLoc)); |
|
283 TLex lexHeight(pFrameSizePtr.Mid(xLoc+1)); |
|
284 lexWidth.Val(iWidth); // Storing into local iWidth variable |
|
285 lexHeight.Val(iHeight); // Storing into local iHeight variable |
|
286 } |
|
287 } |
|
288 else if (id == HXMetaDataKeys::EHXDuration && pDes) |
|
289 { |
|
290 TLex lexDuration(pDes->Des()); |
|
291 lexDuration.Val(iDuration); |
|
292 } |
|
293 else if (id == HXMetaDataKeys::EHXFramesPerSecond && pDes) |
|
294 { |
|
295 TLex lexFramesPerSecond(pDes->Des()); |
|
296 lexFramesPerSecond.Val(iFrameRateInSec); |
|
297 } |
|
298 else if (id == HXMetaDataKeys::EHXClipBitRate && pDes) |
|
299 { |
|
300 TLex lexBitRate(pDes->Des()); |
|
301 lexBitRate.Val(iClipBitRate); |
|
302 } |
|
303 else if (id == HXMetaDataKeys::EHXVideoBitRate && pDes) |
|
304 { |
|
305 TLex lexBitRate(pDes->Des()); |
|
306 lexBitRate.Val(iVideoBitRate); |
|
307 } |
|
308 else if (id == HXMetaDataKeys::EHXAudioBitRate && pDes) |
|
309 { |
|
310 TLex lexBitRate(pDes->Des()); |
|
311 lexBitRate.Val(iAudioBitRate); |
|
312 } |
|
313 |
|
314 } // end for |
|
315 |
|
316 iTotalFrameCount = ( (iDuration+500)/1000 ) * iFrameRateInSec; |
|
317 |
|
318 RDebug::Printf( "THUMBNAILTESTER width=%i", iWidth ); |
|
319 RDebug::Printf( "THUMBNAILTESTER height=%i", iHeight ); |
|
320 RDebug::Printf( "THUMBNAILTESTER frame rate=%i", iFrameRateInSec ); |
|
321 RDebug::Printf( "THUMBNAILTESTER duration=%i", iDuration ); |
|
322 RDebug::Printf( "THUMBNAILTESTER frame count=%i", iTotalFrameCount ); |
|
323 RDebug::Printf( "THUMBNAILTESTER clip bit rate=%i", iClipBitRate ); |
|
324 RDebug::Printf( "THUMBNAILTESTER video bit rate=%i", iVideoBitRate ); |
|
325 RDebug::Printf( "THUMBNAILTESTER audio bit rate=%i", iAudioBitRate ); |
|
326 } |
|
327 |
|
328 void CThumbnailTester::PacketReady(TInt /*aError*/, void *pYuvBuffer, TUint32 /*aYuvBufferSize*/) |
|
329 { |
|
330 // TODO: HANDLE aError |
|
331 |
|
332 iFramesRendered++; |
|
333 iTotalFramesRendered++; |
|
334 |
|
335 // Convert from YUV420 to RGB24. |
|
336 |
|
337 const TInt KBytesPerPixel = 3; // 24-bit rgb takes 3 bytes |
|
338 |
|
339 TUint32 rgbBufferSize = iWidth * iHeight * KBytesPerPixel; |
|
340 TUint8 *pRgbBuffer =(TUint8*) User::AllocL(rgbBufferSize); |
|
341 |
|
342 CYuv2Rgb24* yuvConverter = NULL; |
|
343 TRAPD(err, yuvConverter = new(ELeave) CYuv2Rgb24); |
|
344 |
|
345 // TODO: CHECK ERROR |
|
346 |
|
347 TRAP(err, yuvConverter->ConstructL(iWidth, iHeight, iWidth, iHeight)) |
|
348 |
|
349 // TODO: CHECK ERROR |
|
350 |
|
351 TInt scanLineLength = iWidth * KBytesPerPixel; |
|
352 |
|
353 TUint8* yBuf = (TUint8*)pYuvBuffer; |
|
354 TUint8* uBuf = yBuf + iWidth*iHeight; |
|
355 TUint8* vBuf = uBuf + (iWidth*iHeight)/4; |
|
356 |
|
357 yuvConverter->Convert(yBuf, uBuf, vBuf, iWidth, iHeight, pRgbBuffer, scanLineLength); |
|
358 |
|
359 delete yuvConverter; |
|
360 |
|
361 // Use RGB24 buffer to create CFbsBitmap. |
|
362 |
|
363 CFbsBitmap* pBitmap = NULL; |
|
364 |
|
365 TRAP(err, pBitmap = new (ELeave) CFbsBitmap); |
|
366 if( err == KErrNone ) |
|
367 { |
|
368 err = pBitmap->Create(TSize(iWidth, iHeight), EColor16M); |
|
369 |
|
370 if( err == KErrNone ) |
|
371 { |
|
372 // fill image from rgb buffer to input bitmap buffer |
|
373 TPtr8 linePtr(0,0); |
|
374 TInt lineLength = pBitmap->ScanLineLength(iWidth, EColor16M); |
|
375 for(int j=0, i=0; j<iHeight; j++, i+=lineLength) |
|
376 { |
|
377 linePtr.Set(pRgbBuffer+i, lineLength, lineLength); |
|
378 pBitmap->SetScanLine((TDes8&)linePtr,j); |
|
379 } |
|
380 |
|
381 iGc->Activate(*iSelectionWindow); |
|
382 |
|
383 iSelectionWindow->Invalidate(); |
|
384 iSelectionWindow->BeginRedraw(); |
|
385 |
|
386 iGc->Reset(); |
|
387 |
|
388 iGc->UseFont(iFont); |
|
389 iGc->SetBrushColor(KRgbDarkBlue); |
|
390 |
|
391 iGc->Clear(); |
|
392 |
|
393 // KRgbWhite seems to be having problems (0xffffff) in some emulators, |
|
394 // but 0xfefefe is working, so use that instead of white. |
|
395 iGc->SetPenColor(0xfefefe); |
|
396 |
|
397 TPoint topLeft( iDisplaySize.iWidth/2 - iWidth/2, |
|
398 iDisplaySize.iHeight/2 - iHeight/2 ); |
|
399 iGc->BitBlt( topLeft, pBitmap ); |
|
400 |
|
401 const TInt KColumn = 3; |
|
402 const TInt KRowIncrement = KFontSize + 1; |
|
403 TInt row = KRowIncrement; |
|
404 |
|
405 iBuffer.Format( _L("Frame # %i"), iFramesRendered ); |
|
406 iGc->DrawText( iBuffer, TPoint(KColumn, row) ); |
|
407 row += KRowIncrement; |
|
408 |
|
409 iBuffer.Format( _L("Total frames rendered: %i"), iTotalFramesRendered ); |
|
410 iGc->DrawText( iBuffer, TPoint(KColumn, row) ); |
|
411 row += KRowIncrement; |
|
412 |
|
413 iBuffer.Format( _L("Start time(ms): %i"), iStartPositionInMs ); |
|
414 iGc->DrawText( iBuffer, TPoint(KColumn, row) ); |
|
415 row += KRowIncrement; |
|
416 |
|
417 iBuffer.Format( _L("Display size: %ix%i"), iDisplaySize.iWidth, iDisplaySize.iHeight ); |
|
418 iGc->DrawText( iBuffer, TPoint(KColumn, row) ); |
|
419 row += KRowIncrement; |
|
420 |
|
421 iBuffer.Format( _L("Video size: %ix%i"), iWidth, iHeight ); |
|
422 iGc->DrawText( iBuffer, TPoint(KColumn, row) ); |
|
423 row += KRowIncrement; |
|
424 |
|
425 iBuffer.Format( _L("Total frame count: %i"), iTotalFrameCount ); |
|
426 iGc->DrawText( iBuffer, TPoint(KColumn, row) ); |
|
427 row += KRowIncrement; |
|
428 |
|
429 iBuffer.Format( _L("Duration: %i"), iDuration ); |
|
430 iGc->DrawText( iBuffer, TPoint(KColumn, row) ); |
|
431 row += KRowIncrement; |
|
432 |
|
433 iBuffer.Format( _L("Frame rate: %i"), iFrameRateInSec ); |
|
434 iGc->DrawText( iBuffer, TPoint(KColumn, row) ); |
|
435 row += KRowIncrement; |
|
436 |
|
437 iBuffer.Format( _L("Clip bit rate: %i"), iClipBitRate ); |
|
438 iGc->DrawText( iBuffer, TPoint(KColumn, row) ); |
|
439 row += KRowIncrement; |
|
440 |
|
441 iBuffer.Format( _L("Video bit rate: %i"), iVideoBitRate ); |
|
442 iGc->DrawText( iBuffer, TPoint(KColumn, row) ); |
|
443 row += KRowIncrement; |
|
444 |
|
445 iBuffer.Format( _L("Audio bit rate: %i"), iAudioBitRate ); |
|
446 iGc->DrawText( iBuffer, TPoint(KColumn, row) ); |
|
447 row += KRowIncrement; |
|
448 |
|
449 iGc->DrawText( _L("<Press key to stop then another to exit>"), TPoint(KColumn, iDisplaySize.iHeight-10) ); |
|
450 |
|
451 iSelectionWindow->EndRedraw(); |
|
452 |
|
453 iGc->Deactivate(); |
|
454 |
|
455 iSelectionWindow->SetVisible( ETrue ); |
|
456 } |
|
457 |
|
458 delete pBitmap; |
|
459 } |
|
460 |
|
461 delete pRgbBuffer; |
|
462 |
|
463 User::After( iDelayBetweenFrames ); |
|
464 } |
|
465 |
|
466 void CThumbnailTester::EndOfPackets() |
|
467 { |
|
468 RDebug::Printf( "THUMBNAILTESTER end of packets" ); |
|
469 } |
|
470 |
|
471 GLDEF_C TInt E32Main() |
|
472 { |
|
473 __UHEAP_MARK; |
|
474 |
|
475 CActiveScheduler* scheduler = new CActiveScheduler; |
|
476 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
477 if( scheduler != NULL && cleanup != NULL ) |
|
478 { |
|
479 CActiveScheduler::Install( scheduler ); |
|
480 TRAP_IGNORE( CThumbnailTester::ExecuteL() ); |
|
481 } |
|
482 delete cleanup; |
|
483 delete scheduler; |
|
484 REComSession::FinalClose(); |
|
485 __UHEAP_MARKEND; |
|
486 return 0; |
|
487 } |
|
488 |