diff -r 000000000000 -r 40261b775718 mmlibs/mmfw/tsrc/mmfunittest/srtdecoder/src/testsrtdecoder.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmlibs/mmfw/tsrc/mmfunittest/srtdecoder/src/testsrtdecoder.cpp Tue Feb 02 01:56:55 2010 +0200 @@ -0,0 +1,690 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include +#include + +#include "srtdecoder.h" +#include "srtreader.h" +#include "testsrtdecoder.h" + +_LIT(KSampleSubtitleSRTFilepath1, "c:\\mm\\subtitle1.srt"); +_LIT(KSampleSubtitleSRTFilepath2, "c:\\mm\\subtitle2.srt"); + +// subtitlebmp0.mbm -- subtitlebmp9.mbm: bitmaps for comparison +_LIT(KSubtitleTargetBitmapFilePathSpec, "c:\\mm\\subtitlebmp%d.mbm"); +// subtitlecurbmp0.mbm -- subtitlecurbmp9.mbm: runtime bitmaps for comparison, +// will be removed unless MMF_SUBTITLE_SUPPORT_TEST_SAVEDATA is defined +_LIT(KSubtitleCurrentBitmapFilePathSpec, "c:\\mm\\subtitlecurbmp%d.mbm"); + +// defining MMF_SUBTITLE_SUPPORT_TEST_SAVEDATA means re-creating the test data (bitmaps) for comparison, instead +// of doing the comparison with the existing test data +// at runtime with the spec of KSubtitleCurrentBitmapFilePathSpec +#ifndef MMF_SUBTITLE_SUPPORT_TEST_SAVEDATA +// #define MMF_SUBTITLE_SUPPORT_TEST_SAVEDATA +#endif + +void RTestSrtDecoderStep::InitializeTestStepL(TBool aCreateSrtReaderOnly, const TDesC& aSrtFilePath) + { + __MM_HEAP_MARK; + iSrtReader = CSrtReader::NewL(aSrtFilePath); + + iCreateSrtReaderOnly = aCreateSrtReaderOnly; + if (!iCreateSrtReaderOnly) + { + User::LeaveIfError(iRbsSession.Connect()); + iSrtDecoder = CSrtSubtitleDecoder::NewL(*iSrtReader); + } + } + +void RTestSrtDecoderStep::UnInitializeTestStep() + { + if (!iCreateSrtReaderOnly) + { + iRbsSession.Disconnect(); + delete iSrtDecoder; + } + delete iSrtReader; + __MM_HEAP_MARKEND; + } + +// Implementation of the generic test step +TBool RTestSrtDecoderStep::CompareFilesL(RFs &aFs, const TDesC& aFilePath1, const TDesC& aFilePath2) + { + TBool identical = EFalse; + RFile file1; + RFile file2; + TInt file1Size = 0; + TInt file2Size = 0; + + if (aFilePath1 == aFilePath2) + { + identical = ETrue; + } + else + { + User::LeaveIfError(file1.Open(aFs, aFilePath1, EFileRead)); + CleanupClosePushL(file1); + User::LeaveIfError(file2.Open(aFs, aFilePath2, EFileRead)); + CleanupClosePushL(file2); + + User::LeaveIfError(file1.Size(file1Size)); + User::LeaveIfError(file2.Size(file2Size)); + + if (file1Size == file2Size) + { + TBuf8<256> buffer1; + TBuf8<256> buffer2; + + identical = ETrue; + while(ETrue) + { + User::LeaveIfError(file1.Read(buffer1)); + User::LeaveIfError(file2.Read(buffer2)); + + if (buffer1 != buffer2) + { + identical = EFalse; + break; + } + + if (0 == buffer1.Length()) + { + break; + } + } + } + + CleanupStack::PopAndDestroy(&file2); + CleanupStack::PopAndDestroy(&file1); + } + + return identical; + } + +TBool RTestSrtDecoderStep::IsFontAvailableL(const TDesC& aTypefaceName) + { + TBool avail = EFalse; + TSize bmpSize(100, 100); + + CFbsBitmap* sampleBitmap = new (ELeave) CFbsBitmap(); + CleanupStack::PushL(sampleBitmap); + + User::LeaveIfError(sampleBitmap->Create(bmpSize, EColor16MA)); + + CFbsBitmapDevice* bmpDevice = CFbsBitmapDevice::NewL(sampleBitmap); + CleanupStack::PushL(bmpDevice); + + if (0 != FontUtils::TypefaceAttributes(*bmpDevice, aTypefaceName)) + { + const TInt KSubtitleFontMaxSpecHeights = 128; + CArrayFix *listHeights = new (ELeave) CArrayFixFlat(KSubtitleFontMaxSpecHeights); + CleanupStack::PushL(listHeights); + + FontUtils::GetAvailableHeightsInTwipsL(*bmpDevice, aTypefaceName, *listHeights); + for (TInt i = 0; i < listHeights->Count(); i++) + { + if (KSrtTargetTypefaceHeightInTwips == (*listHeights)[i]) + { + avail = ETrue; + break; + } + } + + CleanupStack::PopAndDestroy(listHeights); + } + + CleanupStack::PopAndDestroy(bmpDevice); + CleanupStack::PopAndDestroy(sampleBitmap); + + return avail; + } + +TBool RTestSrtDecoderStep::CompareBmpFilesL(TInt aStartIndex, TInt aEndIndex, const TDesC& aSrcFilePathSpec, const TDesC& aDestFilePathSpec) + { + TBool identical = ETrue; + TBuf bitmapFilename1; + TBuf bitmapFilename2; + RFs rfs; + User::LeaveIfError(rfs.Connect()); + CleanupClosePushL(rfs); + for (TInt i = aStartIndex; i <= aEndIndex; i++) + { + bitmapFilename1.Format(aDestFilePathSpec, i); + bitmapFilename2.Format(aSrcFilePathSpec, i); + if (!CompareFilesL(rfs, bitmapFilename1, bitmapFilename2)) + { + identical = EFalse; + break; + } + } + CleanupStack::PopAndDestroy(&rfs); + + return identical; + } + +void RTestSrtDecoderStep::DeleteTempFiles(TInt aStartIndex, TInt aEndIndex, const TDesC& aFilePathSpec) + { + TBuf bitmapFilename; + RFs rfs; + + if (KErrNone == rfs.Connect()) + { + for (TInt i = aStartIndex ; i <= aEndIndex; i++) + { + bitmapFilename.Format(aFilePathSpec, i); + BaflUtils::DeleteFile(rfs, bitmapFilename); + } + } + } + + +// Implementation of RTestSrtDecoderStep0002 + +RTestSrtDecoderStep0002::RTestSrtDecoderStep0002() + { + iTestStepName = _L("MM-MMF-SUBTITLE-SRTDECODER-U-0002-HP"); + } + +TVerdict RTestSrtDecoderStep0002::DoTestStepPreambleL() + { + InitializeTestStepL(EFalse, KSampleSubtitleSRTFilepath1); + + // Install the Active Scheduler + iActiveScheduler = new(ELeave) CActiveScheduler; + CActiveScheduler::Install(iActiveScheduler); + iActiveSchedulerStarted = EFalse; + + InitWservL(); + + return EPass; + } + +TVerdict RTestSrtDecoderStep0002::DoTestStepPostambleL() + { + UninitWserv(); + CActiveScheduler::Install(NULL); + delete iActiveScheduler; + iActiveScheduler = NULL; + + UnInitializeTestStep(); + + return EPass; + } + +TVerdict RTestSrtDecoderStep0002::DoTestStepL() + { + INFO_PRINTF1(_L("Enter DoTestStepL")); + TVerdict result = EPass; + + TRAPD(err, TestGetNextFrameL()); + if (KErrNone != err) + { + result = EFail; + ERR_PRINTF2(_L("Error - RTestSrtDecoderStep0002::TestGetNextFrameL failed. error code %d. "), err); + } + + INFO_PRINTF1(_L("Exit DoTestStepL")); + return result; + } + +void RTestSrtDecoderStep0002::InitWservL() + { + TInt err = iWs.Connect(); + + if (err != KErrNone) + { + // Access violation if ws is null + ERR_PRINTF2(_L("Error - Failed to connect to RWsSession. error code %d. "), err); + User::Leave(err); + } + + iScreen = new (ELeave) CWsScreenDevice(iWs); // make device for this session + User::LeaveIfError(iScreen->Construct()); // and complete its construction + + iRootWindow = RWindowGroup(iWs); + User::LeaveIfError(iRootWindow.Construct((TUint32)this, ETrue)); + + iWindow = new(ELeave) RWindow(iWs); + User::LeaveIfError(((RWindow*)iWindow)->Construct(iRootWindow,((TUint32)(this)) + 1)); + iWindow->SetExtent(TPoint(0,0), iScreen->SizeInPixels()); + iWindow->SetVisible(ETrue); + iWindow->SetRequiredDisplayMode(EColor16MA); + + // Light Sky Blue 135-206-250 + TRgb backgroundColour = TRgb(135, 206, 250); + iWindow->SetBackgroundColor(backgroundColour); + + iGc = new(ELeave) CWindowGc(iScreen); + User::LeaveIfError(iGc->Construct()); + + iWindow->Activate(); + iWs.Flush(); + } + +void RTestSrtDecoderStep0002::UninitWserv() + { + if (iWindow) + { + iWindow->Close(); + delete iWindow; + iWindow = NULL; + } + + iRootWindow.Close(); + delete iScreen; + iScreen = NULL; + + delete iGc; + iGc = NULL; + + iWs.Flush(); + iWs.Close(); + } + +void RTestSrtDecoderStep0002::PrepGc() + { + iGc->Activate(*iWindow); + iWindow->Invalidate(); + iWindow->BeginRedraw(); + + iGc->Clear(TRect(iScreen->SizeInPixels())); + iWs.Flush(); + } + +void RTestSrtDecoderStep0002::RetireGc() + { + iGc->Deactivate(); + iWindow->EndRedraw(); + iWs.Flush(); + } + +void RTestSrtDecoderStep0002::DrawBitmap(CFbsBitmap& aBitmap) + { + PrepGc(); + + TSize size = iScreen->SizeInPixels(); + TInt width = size.iWidth; + TInt height = size.iHeight; + TPoint pos(0, 0); + + // Draw a square border + iGc->SetPenColor(TRgb(255,0,0)); + iGc->DrawLine(TPoint(0,0),TPoint(0,height-1)); + iGc->DrawLine (TPoint (0, height-1), TPoint (width-1, height-1)); + iGc->DrawLine(TPoint(width-1,height-1),TPoint(width-1,0)); + iGc->DrawLine (TPoint (width-1, 0), TPoint (0, 0)); + + // Draw a line between the corners of the window + iGc->DrawLine(TPoint(0,0),TPoint(width, height)); + iGc->DrawLine (TPoint (0, height), TPoint (width, 0)); + + // Draw bitmap + iGc->BitBlt(pos, &aBitmap); + + RetireGc(); + } + +void RTestSrtDecoderStep0002::TestGetNextFrameL() + { + // start/stop for multiple times is also tested. + const TInt64 KSrtMicroSecondsInAMilliSecond = 1000; + const TInt64 KSrtMicroSecondsInASecond = KSrtMicroSecondsInAMilliSecond * 1000; + const TInt64 KSrtMicroSecondsInAMinute = KSrtMicroSecondsInASecond * 60; + const TInt64 KSrtMicroSecondsInAnHour = KSrtMicroSecondsInAMinute * 60; + const TInt KSrtSetPosTestCount = 6; + const TInt KSrtNumOfFrames = 10; + + TTimeIntervalMicroSeconds videoPos[KSrtSetPosTestCount] = + { + 0, + KSrtMicroSecondsInAMinute, + 1 * KSrtMicroSecondsInAMinute + 2 * KSrtMicroSecondsInASecond + 1 * KSrtMicroSecondsInAMilliSecond, + 1 * KSrtMicroSecondsInAMinute + 6 * KSrtMicroSecondsInASecond + 20 * KSrtMicroSecondsInAMilliSecond, + 1 * KSrtMicroSecondsInAnHour + 1 * KSrtMicroSecondsInAMinute + 20 * KSrtMicroSecondsInASecond + 1 * KSrtMicroSecondsInAMilliSecond, + 2 * KSrtMicroSecondsInAnHour + }; + + TInt expectedNumOfFrames[KSrtSetPosTestCount] = + { + 10, + 8, + 6, + 6, + 2, + 0 + }; + + // check if the required Font is available before do the bitmap file comparison + TInt requiredFontAvailable = IsFontAvailableL(KSrtTargetTypefaceName); + if (!requiredFontAvailable) + { +#ifdef MMF_SUBTITLE_SUPPORT_TEST_SAVEDATA + INFO_PRINTF1(_L("Required font is not available, cannot save bitmap data. ")); + User::Leave(KErrGeneral); +#else + INFO_PRINTF1(_L("Required font is not available, no bitmap comparison. ")); +#endif //MMF_SUBTITLE_SUPPORT_TEST_SAVEDATA + } + + for (TInt i = 0; i < KSrtSetPosTestCount; i++) + { +#ifdef __WINSCW__ + TBool compareBitmap = (0 == i) && requiredFontAvailable; +#else + TBool compareBitmap = EFalse; +#endif //__WINSCW__ + + TestGetNextFrameByPositionsL(videoPos[i], expectedNumOfFrames[i], compareBitmap); + + // verify the bitmaps + if (compareBitmap) + { +#ifndef MMF_SUBTITLE_SUPPORT_TEST_SAVEDATA + TBool compResult = CompareBmpFilesL(KSrtNumOfFrames - expectedNumOfFrames[i], KSrtNumOfFrames - 1, KSubtitleCurrentBitmapFilePathSpec, KSubtitleTargetBitmapFilePathSpec); + + DeleteTempFiles(KSrtNumOfFrames - expectedNumOfFrames[i], KSrtNumOfFrames - 1, KSubtitleCurrentBitmapFilePathSpec); + + if (!compResult) + { + INFO_PRINTF1(_L("At least one bitmap file does not match the expected one. ")); + User::Leave(KErrGeneral); + } +#endif //MMF_SUBTITLE_SUPPORT_TEST_SAVEDATA + } + } + } + +void RTestSrtDecoderStep0002::TestGetNextFrameByPositionsL(const TTimeIntervalMicroSeconds& aPosition, TInt aExpectedNumOfFrames, TBool aSaveBitmap) + { + TRect dirtyRegion; + TTimeIntervalMicroSeconds displayTime = 0; + TTimeIntervalMicroSeconds displayDuration = 0; + TInt64 tDisplayTime = 0; + TInt64 tDisplayDuration = 0; + TSize bmpSize(600, 300); + TInt numOfFrames = 0; + TInt err = KErrNone; + TBuf bitmapFilename; + + CFbsBitmap* sampleBitmap = new (ELeave) CFbsBitmap(); + CleanupStack::PushL(sampleBitmap); + + User::LeaveIfError(sampleBitmap->Create(bmpSize, EColor16MA)); + + iSrtDecoder->SetVideoPosition(aPosition); + iSrtDecoder->Start(); + + while (KErrNone == err) + { + TRAP(err, iSrtDecoder->GetNextFrameL(*sampleBitmap, dirtyRegion, displayTime, displayDuration)); + if (KErrNone == err) + { + // show bitmap + DrawBitmap(*sampleBitmap); + + // save bitmap for the possible comparison + if (aSaveBitmap) + { + bitmapFilename.Format(KSubtitleCurrentBitmapFilePathSpec, numOfFrames); + User::LeaveIfError(sampleBitmap->Save(bitmapFilename)); + } + + if ((dirtyRegion.iTl.iX >= dirtyRegion.iBr.iX) || + (dirtyRegion.iTl.iY >= dirtyRegion.iBr.iY)) + { + INFO_PRINTF2(_L("Invalid dirty region received. (frame %d)"), numOfFrames); + User::Leave(KErrGeneral); + } + + tDisplayTime = displayTime.Int64()/1000; + tDisplayDuration = displayDuration.Int64()/1000; + INFO_PRINTF4(_L("Frame[%d]: displayTime: %dms, displayDuration: %dms."), + numOfFrames, + I64LOW(tDisplayTime), + I64LOW(tDisplayDuration)); + + numOfFrames++; + } + } + + CleanupStack::PopAndDestroy(sampleBitmap); + + iSrtDecoder->Stop(); + + if (KErrEof != err) + { + User::Leave(err); + } + + if (aExpectedNumOfFrames != numOfFrames) + { + INFO_PRINTF2(_L("The number of frame (%d) is unexpected. "), numOfFrames); + User::Leave(KErrGeneral); + } + } + + +// Implementation of RTestSrtDecoderStep0101 + +RTestSrtDecoderStep0101::RTestSrtDecoderStep0101() + { + iTestStepName = _L("MM-MMF-SUBTITLE-SRTDECODER-U-0101-HP"); + } + +TVerdict RTestSrtDecoderStep0101::DoTestStepPreambleL() + { + InitializeTestStepL(EFalse, KSampleSubtitleSRTFilepath2); + + return EPass; + } + +TVerdict RTestSrtDecoderStep0101::DoTestStepPostambleL() + { + UnInitializeTestStep(); + + return EPass; + } + +TVerdict RTestSrtDecoderStep0101::DoTestStepL() + { + INFO_PRINTF1(_L("Enter DoTestStepL")); + TVerdict result = EPass; + + TRAPD(err, TestGetNextFrameL()); + if (KErrNone != err) + { + result = EFail; + ERR_PRINTF2(_L("Error - RTestSrtDecoderStep0101::TestGetNextFrameL failed. error code %d. "), err); + INFO_PRINTF1(_L("Exit CSrtDecoder")); + return result; + } + + INFO_PRINTF1(_L("Exit DoTestStepL")); + return result; + } + +void RTestSrtDecoderStep0101::TestGetNextFrameL() + { + TInt numOfValidFrame = 0; + const TInt KSrtCase0101ExpectedValidFrame = 6; + TRect dirtyRegion; + TTimeIntervalMicroSeconds displayTime = 0; + TTimeIntervalMicroSeconds displayDuration = 0; + TSize bmpSize(320, 120); + + CFbsBitmap* sampleBitmap = new (ELeave) CFbsBitmap(); + CleanupStack::PushL(sampleBitmap); + + TInt err = sampleBitmap->Create( + bmpSize, + EColor16MA + ); + User::LeaveIfError(err); + + iSrtDecoder->SetVideoPosition(0); + iSrtDecoder->Start(); + + while (KErrNone == err) + { + TRAP(err, iSrtDecoder->GetNextFrameL(*sampleBitmap, dirtyRegion, displayTime, displayDuration)); + if (KErrNone == err) + { + numOfValidFrame++; + } + else if (KErrArgument == err) + { + err = KErrNone; + } + } + + CleanupStack::PopAndDestroy(sampleBitmap); + + iSrtDecoder->Stop(); + + if (err != KErrEof) + { + User::Leave(err); + } + + if (KSrtCase0101ExpectedValidFrame != numOfValidFrame) + { + INFO_PRINTF2(_L("The number of valid frame (%d) is unexpected. "), numOfValidFrame); + User::Leave(KErrGeneral); + } + } + +// Implementation of RTestSrtDecoderStep0103 + +RTestSrtDecoderStep0103::RTestSrtDecoderStep0103() + { + iTestStepName = _L("MM-MMF-SUBTITLE-SRTDECODER-U-0103-HP"); + } + +TVerdict RTestSrtDecoderStep0103::DoTestStepPreambleL() + { + User::LeaveIfError(RFbsSession::Connect()); + + return EPass; + } + +TVerdict RTestSrtDecoderStep0103::DoTestStepPostambleL() + { + RFbsSession::Disconnect(); + + return EPass; + } + +TVerdict RTestSrtDecoderStep0103::DoTestStepL() + { + INFO_PRINTF1(_L("Enter DoTestStepL")); + TVerdict result = EFail; + TSize bmpSize(120, 320); + + CFbsBitmap* sampleBitmap = new (ELeave) CFbsBitmap(); + CleanupStack::PushL(sampleBitmap); + User::LeaveIfError(sampleBitmap->Create(bmpSize, EColor16MA)); + + for (TInt failRate = 1; ; ++failRate) + { + __UHEAP_SETFAIL(RHeap::EFailNext, failRate); + __UHEAP_MARK; + + TRAPD(error, TestGetNextFrameL(*sampleBitmap)); + RDebug::Printf("Ending iteration %d. Result = %d. Failures = %d", failRate, error, __UHEAP_CHECKFAILURE); + + __UHEAP_MARKEND; + + if ((error != KErrNone) && (error != KErrNoMemory)) + { + ERR_PRINTF3(_L("RTestSrtDecoderStep0103: TESTS FAILED TO COMPLETE (failRate=%i) error code: %d\n"), failRate, error); + break; + } + + TAny* const pointer = User::Alloc(1); + User::Free(pointer); + if (!pointer) + { + result = EPass; + break; + } + } + + __UHEAP_RESET; + + CleanupStack::PopAndDestroy(sampleBitmap); + + INFO_PRINTF1(_L("Exit DoTestStepL")); + return result; + } + +void RTestSrtDecoderStep0103::TestGetNextFrameL(CFbsBitmap& aBitmap) + { + TRect dirtyRegion; + CSrtReader *srtReader = CSrtReader::NewL(KSampleSubtitleSRTFilepath1); + CleanupStack::PushL(srtReader); + + CSrtSubtitleDecoder *srtDecoder = CSrtSubtitleDecoder::NewL(*srtReader); + CleanupStack::PushL(srtDecoder); + + TInt err = KErrNone; + TTimeIntervalMicroSeconds displayTime = 0; + TTimeIntervalMicroSeconds displayDuration = 0; + + srtDecoder->SetVideoPosition(0); + srtDecoder->Start(); + + while (KErrNone == err) + { + TRAP(err, srtDecoder->GetNextFrameL(aBitmap, dirtyRegion, displayTime, displayDuration)); + } + + if (err != KErrEof) + { + User::LeaveIfError(err); + } + + srtDecoder->Stop(); + + CleanupStack::PopAndDestroy(srtDecoder); + CleanupStack::PopAndDestroy(srtReader); + } + +RTestSrtDecoderStep0105::RTestSrtDecoderStep0105() + { + iTestStepName = _L("MM-MMF-SUBTITLE-SRTDECODER-U-0105-HP"); + } + +TVerdict RTestSrtDecoderStep0105::DoTestStepL() + { + iSrtDecoder->Start(); + iSrtDecoder->Start(); + + ERR_PRINTF1(_L("Panic expected, so failing")); + return EFail; + } + +TVerdict RTestSrtDecoderStep0105::DoTestStepPreambleL() + { + InitializeTestStepL(EFalse, KSampleSubtitleSRTFilepath1); + return EPass; + } + +TVerdict RTestSrtDecoderStep0105::DoTestStepPostambleL() + { + UnInitializeTestStep(); + return EPass; + }