1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmplugins/lib3gpunittest/src/tsu_3gplibrary_parse_compose.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1410 @@
1.4 +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "tsu_3gplibrary_parse_compose.h"
1.20 +
1.21 +const TUint16 KAudioModeSet = 0x81ff;
1.22 +const TReal KMillisecondsInSecond = 1000;
1.23 +const TReal KOneHalf = 0.5;
1.24 +const TInt KLargeFileWriteBufferSize = 16384; // 16K
1.25 +const TInt KLargeFileWriteBufferMaxCount = 15;
1.26 +
1.27 +_LIT( KAvcBaseline, "Baseline" );
1.28 +_LIT( KAvcMain, "Main" );
1.29 +_LIT( KAvcExtended, "Extended" );
1.30 +_LIT( KAvcHigh, "High" );
1.31 +
1.32 +const static TDesC* KAvcProfileNames[] = {
1.33 + &KAvcBaseline,
1.34 + &KAvcMain,
1.35 + &KAvcExtended,
1.36 + &KAvcHigh
1.37 + };
1.38 +
1.39 +
1.40 +C3GPLibParseComposeFile::C3GPLibParseComposeFile() :
1.41 + iCompareOriginal(EFalse),
1.42 + iLargeFile(EFalse)
1.43 + {
1.44 + }
1.45 +
1.46 +TVerdict C3GPLibParseComposeFile::doTestStepPreambleL()
1.47 + {
1.48 + #ifdef __WINSCW__
1.49 + _LIT(KInputDir, "inputDirEmul");
1.50 + _LIT(KOutputDir, "outputDirEmul");
1.51 + #else
1.52 + _LIT(KInputDir, "inputDirHw");
1.53 + _LIT(KOutputDir, "outputDirHw");
1.54 + #endif
1.55 + // ensure test always starts with clean results
1.56 + SetTestStepResult(EPass);
1.57 + SetTestStepError(KErrNone);
1.58 +
1.59 + // ensure there's always a Active Scheduler for the Composer
1.60 + if (!CActiveScheduler::Current())
1.61 + {
1.62 + iScheduler = new (ELeave) CActiveScheduler;
1.63 + CActiveScheduler::Install(iScheduler);
1.64 + }
1.65 +
1.66 + User::LeaveIfError(iFs.Connect());
1.67 + // retrieve the input files' directory
1.68 + TPtrC inputFileDir;
1.69 + TBool composeFile = EFalse;
1.70 + TPtrC outputFileDir;
1.71 + if (GetStringFromConfig(ConfigSection(), KInputDir, inputFileDir))
1.72 + {
1.73 + if (inputFileDir.Length() == 0)
1.74 + {
1.75 + ERR_PRINTF1(_L("Ensure input directory is specified."));
1.76 + SetTestStepResult(EInconclusive);
1.77 + return TestStepResult();
1.78 + }
1.79 + else
1.80 + {
1.81 + iInputDir.CreateL(inputFileDir);
1.82 + }
1.83 +
1.84 + GetIntFromConfig(ConfigSection(), _L("expectedFailure"), iExpectedNumberOfFailure);
1.85 +
1.86 + if (GetBoolFromConfig(ConfigSection(), _L("composeFile"), composeFile))
1.87 + {
1.88 + if (composeFile)
1.89 + {
1.90 + if (GetStringFromConfig(ConfigSection(), KOutputDir, outputFileDir))
1.91 + {
1.92 + if (outputFileDir.Length() == 0)
1.93 + {
1.94 + ERR_PRINTF1(_L("Ensure output directory is specified."));
1.95 + SetTestStepResult(EInconclusive);
1.96 + return TestStepResult();
1.97 + }
1.98 + else if (outputFileDir == inputFileDir)
1.99 + {
1.100 + ERR_PRINTF1(_L("Ensure output directory is not the same as input directory."));
1.101 + SetTestStepResult(EInconclusive);
1.102 + return TestStepResult();
1.103 + }
1.104 + else if (!GetIntFromConfig(ConfigSection(), _L("fileFormat"), iFileFormat))
1.105 + {
1.106 + ERR_PRINTF1(_L("Ensure a output file format is specified."));
1.107 + SetTestStepResult(EInconclusive);
1.108 + return TestStepResult();
1.109 + }
1.110 +
1.111 + GetIntFromConfig(ConfigSection(), _L("composeFlag"), iComposeFlag);
1.112 + GetBoolFromConfig(ConfigSection(), _L("compareOriginal"), iCompareOriginal);
1.113 + GetBoolFromConfig(ConfigSection(), _L("largeFile"), iLargeFile);
1.114 + }
1.115 + else
1.116 + {
1.117 + ERR_PRINTF1(_L("Ensure output directory is specified."));
1.118 + SetTestStepResult(EInconclusive);
1.119 + }
1.120 + }
1.121 + }
1.122 + }
1.123 + else
1.124 + {
1.125 + ERR_PRINTF1(_L("Ensure input directory is specified."));
1.126 + SetTestStepResult(EInconclusive);
1.127 + }
1.128 +
1.129 + if (TestStepResult() == EPass)
1.130 + {
1.131 + // Create a list of all files contained in the input directory
1.132 + User::LeaveIfError(iFs.GetDir(inputFileDir, KEntryAttNormal, ESortNone, iDirList));
1.133 +
1.134 + if (!iDirList || iDirList->Count() == 0)
1.135 + {
1.136 + ERR_PRINTF1(_L("Input directory is empty."));
1.137 + SetTestStepResult(EInconclusive);
1.138 + }
1.139 + }
1.140 +
1.141 + if (TestStepResult() == EPass)
1.142 + {
1.143 + iParser = C3GPParse::NewL();
1.144 + if (composeFile)
1.145 + {
1.146 + if (iLargeFile)
1.147 + {
1.148 + iComposer = C3GPCompose::NewL(KLargeFileWriteBufferSize, KLargeFileWriteBufferMaxCount);
1.149 + }
1.150 + else
1.151 + {
1.152 + iComposer = C3GPCompose::NewL();
1.153 + }
1.154 +
1.155 + iOutputDir.CreateL(outputFileDir);
1.156 + TInt err = iFs.MkDirAll(iOutputDir);
1.157 + if (err != KErrNone && err != KErrAlreadyExists)
1.158 + {
1.159 + User::Leave(err);
1.160 + }
1.161 + }
1.162 + }
1.163 +
1.164 + return TestStepResult();
1.165 + }
1.166 +
1.167 +TVerdict C3GPLibParseComposeFile::doTestStepL()
1.168 + {
1.169 + if( TestStepResult() == EPass)
1.170 + {
1.171 + TInt failCount = 0;
1.172 + TInt fileCount = 0;
1.173 + RBuf filePath;
1.174 + CleanupClosePushL(filePath);
1.175 + filePath.CreateL(KMaxFileName);
1.176 +
1.177 + for (TInt i = 0; i < iDirList->Count(); i++)
1.178 + {
1.179 + const TEntry& entry = (*iDirList)[i];
1.180 + if (!entry.IsDir())
1.181 + {
1.182 + fileCount++;
1.183 +
1.184 + filePath.Copy(iInputDir);
1.185 + filePath.Append(entry.iName);
1.186 +
1.187 + INFO_PRINTF2(_L("ParseAndComposeL: file=%S"), &filePath);
1.188 + TRAPD(err, ParseFileL(filePath));
1.189 + INFO_PRINTF2(_L("ParseAndComposeL returns: err = %d"), err);
1.190 + if( err != KErrNone )
1.191 + {
1.192 + iParser->Complete();
1.193 + if (iComposer)
1.194 + {
1.195 + iComposer->Complete();
1.196 + }
1.197 + failCount++;
1.198 + }
1.199 + else
1.200 + {
1.201 + if (iCompareOriginal && iComposer)
1.202 + {
1.203 + if (!CompareInputOuputFileL(filePath))
1.204 + {
1.205 + ERR_PRINTF1(_L("Input & output file is not the same"));
1.206 + failCount ++;
1.207 + }
1.208 + else
1.209 + {
1.210 + INFO_PRINTF1(_L("Input & output file is the same."));
1.211 + }
1.212 + }
1.213 + }
1.214 + }
1.215 + }
1.216 +
1.217 + // clean up
1.218 + CleanupStack::PopAndDestroy(&filePath);
1.219 +
1.220 + INFO_PRINTF3(_L("%d of %d files failed"), failCount, fileCount);
1.221 + if (failCount != iExpectedNumberOfFailure)
1.222 + {
1.223 + ERR_PRINTF2(_L("Expected failure: %d - Test Failed"), iExpectedNumberOfFailure);
1.224 + SetTestStepResult(EFail);
1.225 + }
1.226 + }
1.227 +
1.228 + return TestStepResult();
1.229 + }
1.230 +
1.231 +TVerdict C3GPLibParseComposeFile::doTestStepPostambleL()
1.232 + {
1.233 + if( iScheduler )
1.234 + {
1.235 + CActiveScheduler::Install(NULL);
1.236 + delete iScheduler;
1.237 + }
1.238 +
1.239 + iOutputDir.Close();
1.240 + iInputDir.Close();
1.241 + iComposedFile.Close();
1.242 +
1.243 + delete iDirList;
1.244 +
1.245 + iParsedFileHandle64.Close();
1.246 + iComposedFileHandle64.Close();
1.247 + iFs.Close();
1.248 +
1.249 + delete iParser;
1.250 + if (iComposer)
1.251 + {
1.252 + delete iComposer;
1.253 + }
1.254 +
1.255 + return TestStepResult();
1.256 + }
1.257 +
1.258 +void C3GPLibParseComposeFile::ParseFileL(const TDesC& aInputFile)
1.259 + {
1.260 + ASSERT(iParser);
1.261 + TInt err = 0;
1.262 +
1.263 + if (iLargeFile)
1.264 + {
1.265 + iParsedFileHandle64.Close();
1.266 + err = iParsedFileHandle64.Open(iFs, aInputFile, EFileShareReadersOrWriters);
1.267 + if (err == KErrNone)
1.268 + {
1.269 + err = iParser->Open(iParsedFileHandle64);
1.270 + }
1.271 + }
1.272 + else
1.273 + {
1.274 + err = iParser->Open(aInputFile);
1.275 + }
1.276 +
1.277 + if (err != KErrNone)
1.278 + {
1.279 + ERR_PRINTF2(_L("C3GPParse::Open() returns %d"), err);
1.280 + User::Leave(err);
1.281 + }
1.282 +
1.283 + //
1.284 + // Retrieve Video Properties
1.285 + //
1.286 + T3GPVideoPropertiesBase* videoProperties = NULL;
1.287 + CleanupStack::PushL(videoProperties);
1.288 +
1.289 + RBuf8 videoDecoderSpecificInfo;
1.290 + CleanupClosePushL(videoDecoderSpecificInfo);
1.291 +
1.292 + TUint videoLengthInMs = 0;
1.293 +
1.294 + err = ParseVideoProperties(*iParser, videoDecoderSpecificInfo, videoProperties, videoLengthInMs);
1.295 + if (err != KErrNone && err != KErrNotSupported)
1.296 + {
1.297 + ERR_PRINTF2(_L("ParseVideoProperties failed: err = %d"), err);
1.298 + User::Leave(err);
1.299 + }
1.300 +
1.301 + //
1.302 + // Retrieve Audio Properties
1.303 + //
1.304 + T3GPAudioPropertiesBase* audioProperties = NULL;
1.305 + CleanupStack::PushL(audioProperties);
1.306 +
1.307 + RBuf8 audioDecoderSpecificInfo;
1.308 + CleanupClosePushL(audioDecoderSpecificInfo);
1.309 +
1.310 + TUint audioLengthInMs = 0;
1.311 + err = ParseAudioProperties(*iParser, audioDecoderSpecificInfo, audioProperties, audioLengthInMs);
1.312 + if( err != KErrNone && err != KErrNotSupported)
1.313 + {
1.314 + ERR_PRINTF2(_L("ParseAudioProperties failed: err = %d"), err);
1.315 + User::Leave(err);
1.316 + }
1.317 +
1.318 + if (!videoProperties && !audioProperties)
1.319 + {
1.320 + ERR_PRINTF1(_L("File contains neither video nor audio data"));
1.321 + User::Leave(KErrNotFound);
1.322 + }
1.323 +
1.324 + //
1.325 + // Prepare for the Composer if file output is expected
1.326 + //
1.327 + if (iComposer)
1.328 + {
1.329 + RBuf outputFile;
1.330 + CleanupClosePushL(outputFile);
1.331 +
1.332 + outputFile.CreateL(KMaxFileName);
1.333 + outputFile.Copy(iOutputDir);
1.334 +
1.335 + TParsePtrC parsePtr(aInputFile);
1.336 + TPtrC name = parsePtr.NameAndExt();
1.337 +
1.338 + outputFile.Append(parsePtr.NameAndExt());
1.339 +
1.340 + if (iLargeFile)
1.341 + {
1.342 + iComposedFileHandle64.Close();
1.343 + err = iComposedFileHandle64.Create(iFs, outputFile, EFileShareAny|EFileStream|EFileWrite);
1.344 + if (err == KErrAlreadyExists)
1.345 + {
1.346 + err = iComposedFileHandle64.Replace(iFs, outputFile, EFileShareAny|EFileStream|EFileWrite);
1.347 + }
1.348 +
1.349 + if (err == KErrNone)
1.350 + {
1.351 + err = iComposer->Open((T3GPFileFormatType)iFileFormat, videoProperties, audioProperties, iComposedFileHandle64, iComposeFlag);
1.352 + }
1.353 + }
1.354 + else
1.355 + {
1.356 + err = iComposer->Open((T3GPFileFormatType)iFileFormat, videoProperties, audioProperties, outputFile, iComposeFlag);
1.357 + }
1.358 +
1.359 + if (err != KErrNone)
1.360 + {
1.361 + ERR_PRINTF2(_L("C3GPCompose::Open failed: err = %d"), err);
1.362 + User::Leave(err);
1.363 + }
1.364 +
1.365 + CleanupStack::PopAndDestroy(&outputFile);
1.366 + }
1.367 +
1.368 + //
1.369 + // Parse and compose (if specified) video / audio frame data
1.370 + //
1.371 + ReadWriteAudioVideoFramesL(videoProperties, audioProperties, videoLengthInMs, audioLengthInMs);
1.372 +
1.373 + //
1.374 + // Clean up
1.375 + //
1.376 + CleanupStack::PopAndDestroy(4);
1.377 + // audioDecoderSpecificInfo
1.378 + // audioProperties
1.379 + // videoDecoderSpecificInfo
1.380 + // videoProperties
1.381 +
1.382 + if (iComposer)
1.383 + {
1.384 + err = iComposer->Complete();
1.385 + if (err != KErrNone)
1.386 + {
1.387 + ERR_PRINTF1(_L("aComposer->Complete() failed"));
1.388 + User::Leave(err);
1.389 + }
1.390 +
1.391 + if (iLargeFile)
1.392 + {
1.393 + iComposedFileHandle64.Close();
1.394 + }
1.395 + }
1.396 +
1.397 + err = iParser->Complete();
1.398 + if (err != KErrNone)
1.399 + {
1.400 + ERR_PRINTF1(_L("aParser->Complete() failed"));
1.401 + User::Leave(err);
1.402 + }
1.403 +
1.404 + if (iLargeFile)
1.405 + {
1.406 + iParsedFileHandle64.Close();
1.407 + }
1.408 +
1.409 + INFO_PRINTF1(_L("C3GPLibParseComposeFile::ParseAndComposeL OUT"));
1.410 + }
1.411 +
1.412 +void C3GPLibParseComposeFile::ReadWriteAudioVideoFramesL(const T3GPVideoPropertiesBase* aVideoProperties,
1.413 + const T3GPAudioPropertiesBase* aAudioProperties,
1.414 + TUint aVideoLengthInMs,
1.415 + TUint aAudioLengthInMs)
1.416 + {
1.417 + ASSERT(iParser);
1.418 +
1.419 + TUint videoLengthInTS = 0;
1.420 + TUint audioLengthInTS = 0;
1.421 + if (aVideoProperties)
1.422 + {
1.423 + // The "+KOneHalf" in the following calculation has the effect of rounding
1.424 + // to the nearest integer instead of just flooring it when converting from
1.425 + // TReal to TUint.
1.426 + // This is to avoid videoLengthInTS being off by one and leading to false
1.427 + // positives when the video properties are compared later on.
1.428 + videoLengthInTS = (TUint) ((TReal)(aVideoLengthInMs * aVideoProperties->iTimescale) / KMillisecondsInSecond + KOneHalf );
1.429 + }
1.430 + if (aAudioProperties)
1.431 + {
1.432 + // The "+KOneHalf" in the following calculation has the effect of rounding
1.433 + // to the nearest integer instead of just flooring it when converting from
1.434 + // TReal to TUint.
1.435 + // This is to avoid audioLengthInTS being off by one and leading to false
1.436 + // positives when the audio properties are compared later on.
1.437 + audioLengthInTS = (TUint) ((TReal)(aAudioLengthInMs * aAudioProperties->iTimescale) / KMillisecondsInSecond + KOneHalf );
1.438 + }
1.439 +
1.440 + TInt framePerSample1 = 0;
1.441 + TInt framePerSample2 = 0;
1.442 + TUint audioTS1 = 0;
1.443 + TUint audioTS2 = 0;
1.444 + RBuf8 audioBuf1;
1.445 + RBuf8 audioBuf2;
1.446 + CleanupClosePushL(audioBuf1);
1.447 + CleanupClosePushL(audioBuf2);
1.448 +
1.449 + TUint videoTS1;
1.450 + TUint videoTS2;
1.451 + TBool keyFrame1;
1.452 + TBool keyFrame2;
1.453 + T3GPFrameDependencies dep1;
1.454 + T3GPFrameDependencies dep2;
1.455 + RBuf8 videoBuf1;
1.456 + RBuf8 videoBuf2;
1.457 + CleanupClosePushL(videoBuf1);
1.458 + CleanupClosePushL(videoBuf2);
1.459 +
1.460 + TInt err = KErrNone;
1.461 + T3GPFrameType frameType;
1.462 +
1.463 + RArray<T3GPFrameType> frameTypeArray(10);
1.464 + CleanupClosePushL(frameTypeArray);
1.465 +
1.466 + TInt videoFrameCount = 0;
1.467 + TInt audioFrameCount = 0;
1.468 +
1.469 + while (err == KErrNone)
1.470 + {
1.471 + err = iParser->GetFrameType(frameType);
1.472 + if (err == KErrNone)
1.473 + {
1.474 + switch(frameType)
1.475 + {
1.476 + case E3GPAudio:
1.477 + audioFrameCount++;
1.478 + frameTypeArray.AppendL(frameType);
1.479 + err = ReadAudioFrames(*iParser, audioBuf1, framePerSample1, audioTS1);
1.480 + audioBuf1.Close();
1.481 + break;
1.482 +
1.483 + case E3GPVideo:
1.484 + videoFrameCount++;
1.485 + frameTypeArray.AppendL(frameType);
1.486 + err = ReadVideoFrame(*iParser, videoBuf1, keyFrame1, videoTS1, dep1);
1.487 + videoBuf1.Close();
1.488 + break;
1.489 +
1.490 + default:
1.491 + ERR_PRINTF1(_L("GetFrameType retrieves an unsupported frame type"));
1.492 + User::Leave(KErrUnknown);
1.493 + break;
1.494 + }
1.495 +
1.496 + // if there's anything wrong w/ retrieving the frame, exit the function now
1.497 + User::LeaveIfError(err);
1.498 + }
1.499 + }
1.500 +
1.501 + INFO_PRINTF2(_L("ReadWriteAudioVideoFramesL read %d video frames."), videoFrameCount);
1.502 + INFO_PRINTF2(_L("ReadWriteAudioVideoFramesL read %d audio frames."), audioFrameCount);
1.503 +
1.504 + // reset the video and audio cursor at the beginning of the clip
1.505 + TUint videoPos = 0;
1.506 + TUint audioPos = 0;
1.507 + iParser->Seek(0, EFalse, videoPos, audioPos);
1.508 +
1.509 + videoFrameCount = 0;
1.510 + audioFrameCount = 0;
1.511 +
1.512 + if (iComposer)
1.513 + {
1.514 + // if the data should be supplied into a composer to construct an output file
1.515 + TInt index = 0;
1.516 + while (index < frameTypeArray.Count())
1.517 + {
1.518 + frameType = frameTypeArray[index++];
1.519 + switch (frameType)
1.520 + {
1.521 + case E3GPAudio:
1.522 + if (audioBuf1.Length() == 0)
1.523 + {
1.524 + User::LeaveIfError(ReadAudioFrames(*iParser, audioBuf1, framePerSample1, audioTS1));
1.525 + }
1.526 + err = ReadAudioFrames(*iParser, audioBuf2, framePerSample2, audioTS2);
1.527 +
1.528 + if (audioBuf1.Length() > 0 && audioBuf2.Length() > 0 ||
1.529 + audioBuf1.Length() > 0 && err == KErrNotFound)
1.530 + {
1.531 + TUint duration = 0;
1.532 + if (audioBuf2.Length() == 0)
1.533 + {
1.534 + // duration for the last batch of audio frames = total audio length - the 2nd last audio frame
1.535 + duration = audioLengthInTS - audioTS1;
1.536 + }
1.537 + else
1.538 + {
1.539 + duration = audioTS2 - audioTS1;
1.540 + }
1.541 +
1.542 + User::LeaveIfError(iComposer->WriteAudioFrames(audioBuf1, duration));
1.543 + audioFrameCount++;
1.544 +
1.545 + audioBuf1.Close();
1.546 + audioBuf1.Swap(audioBuf2);
1.547 + framePerSample1 = framePerSample2;
1.548 + audioTS1 = audioTS2;
1.549 + }
1.550 + break;
1.551 +
1.552 + case E3GPVideo:
1.553 + if (videoBuf1.Length() == 0)
1.554 + {
1.555 + User::LeaveIfError(ReadVideoFrame(*iParser, videoBuf1, keyFrame1, videoTS1, dep1));
1.556 + }
1.557 + err = ReadVideoFrame(*iParser, videoBuf2, keyFrame2, videoTS2, dep2);
1.558 +
1.559 + if (videoBuf1.Length() > 0 && videoBuf2.Length() > 0 ||
1.560 + videoBuf1.Length() > 0 && err == KErrNotFound)
1.561 + {
1.562 + TUint duration = 0;
1.563 + if (videoBuf2.Length() == 0)
1.564 + {
1.565 + // duration for the last batch of audio frames = total audio length - the 2nd last audio frame
1.566 + duration = videoLengthInTS - videoTS1;
1.567 + }
1.568 + else
1.569 + {
1.570 + duration = videoTS2 - videoTS1;
1.571 + }
1.572 +
1.573 + User::LeaveIfError(iComposer->WriteVideoFrame(videoBuf1, duration, keyFrame1, dep1));
1.574 + videoFrameCount++;
1.575 +
1.576 + videoBuf1.Close();
1.577 + videoBuf1.Swap(videoBuf2);
1.578 + keyFrame1 = keyFrame2;
1.579 + videoTS1 = videoTS2;
1.580 + dep1.iDependsOn = dep2.iDependsOn;
1.581 + dep1.iIsDependedOn = dep2.iIsDependedOn;
1.582 + dep1.iHasRedundancy = dep2.iHasRedundancy;
1.583 + }
1.584 + break;
1.585 +
1.586 + default:
1.587 + ERR_PRINTF1(_L("Unknown frame type detected."));
1.588 + User::Leave(KErrUnknown);
1.589 + break;
1.590 + }
1.591 + } // end of while loop
1.592 + } // if (iComposer)
1.593 +
1.594 + CleanupStack::PopAndDestroy(5);
1.595 +
1.596 + INFO_PRINTF2(_L("ReadWriteAudioVideoFramesL wrote %d video frames."), videoFrameCount);
1.597 + INFO_PRINTF2(_L("ReadWriteAudioVideoFramesL wrote %d audio frames."), audioFrameCount);
1.598 + }
1.599 +
1.600 +TInt C3GPLibParseComposeFile::GetAudioDecoderSpecificInfo(RBuf8& aBuffer)
1.601 + {
1.602 + ASSERT(iParser);
1.603 +
1.604 + TInt size;
1.605 + TInt err = iParser->GetAudioDecoderSpecificInfoSize(size);
1.606 + if( err != KErrNone )
1.607 + {
1.608 + ERR_PRINTF2(_L("GetAudioDecoderSpecificInfoSize() failed: %d"), err);
1.609 + return err;
1.610 + }
1.611 +
1.612 + err = aBuffer.Create(size);
1.613 + if( err != KErrNone )
1.614 + {
1.615 + ERR_PRINTF1(_L("Create buffer failed"));
1.616 + return err;
1.617 + }
1.618 +
1.619 + err = iParser->GetAudioDecoderSpecificInfo(aBuffer);
1.620 + if( err != KErrNone )
1.621 + {
1.622 + ERR_PRINTF2(_L("GetAudioDecoderSpecificInfo() failed: %d"), err);
1.623 + }
1.624 +
1.625 + return err;
1.626 + }
1.627 +
1.628 +TInt C3GPLibParseComposeFile::ParseVideoProperties(C3GPParse& aParser,
1.629 + RBuf8& aDecoderSpecificInfo,
1.630 + T3GPVideoPropertiesBase*& aProperties,
1.631 + TUint& aLengthInMs)
1.632 + {
1.633 + ASSERT(iParser);
1.634 +
1.635 + T3GPVideoType type;
1.636 + TReal frameRate;
1.637 + TUint avgBitRate;
1.638 + TSize size;
1.639 + TUint timeScale;
1.640 +
1.641 + TInt err = aParser.GetVideoProperties(type, aLengthInMs, frameRate, avgBitRate, size, timeScale);
1.642 + if ((err != KErrNone) && (err != KErrNotSupported))
1.643 + {
1.644 + ERR_PRINTF2(_L("aParser->GetVideoProperties failed: %d"), err);
1.645 + return err;
1.646 + }
1.647 +
1.648 + switch(type)
1.649 + {
1.650 + case E3GPMpeg4Video:
1.651 + {
1.652 + INFO_PRINTF1(_L("Video Type: Mpeg4"));
1.653 + err = GetVideoDecoderSpecificInfo(aDecoderSpecificInfo);
1.654 + if (err == KErrNone)
1.655 + {
1.656 + aProperties = new T3GPVideoPropertiesMpeg4Video(timeScale, size,
1.657 + 64000, avgBitRate, aDecoderSpecificInfo);
1.658 + if (!aProperties)
1.659 + {
1.660 + ERR_PRINTF1(_L("T3GPVideoPropertiesMpeg4Video allocation failed"));
1.661 + err = KErrNoMemory;
1.662 + }
1.663 + }
1.664 + break;
1.665 + }
1.666 +
1.667 + case E3GPAvcProfileBaseline:
1.668 + case E3GPAvcProfileMain:
1.669 + case E3GPAvcProfileExtended:
1.670 + case E3GPAvcProfileHigh:
1.671 + {
1.672 + err = GetVideoDecoderSpecificInfo(aDecoderSpecificInfo);
1.673 + if (err == KErrNone)
1.674 + {
1.675 + INFO_PRINTF2(_L("Video Type: Avc Profile %S"), KAvcProfileNames[type-E3GPAvcProfileBaseline] );
1.676 + aProperties = new T3GPVideoPropertiesAvc(timeScale, size, aDecoderSpecificInfo);
1.677 + if (!aProperties)
1.678 + {
1.679 + ERR_PRINTF1(_L("T3GPVideoPropertiesAvc allocation failed"));
1.680 + err = KErrNoMemory;
1.681 + }
1.682 + else
1.683 + {
1.684 + // T3GPVideoPropertiesAvc defaults the video type to AVC baseline profile.
1.685 + // Need to override that here because we want to check for the specific
1.686 + // profile in this test.
1.687 + aProperties->iType = type;
1.688 + }
1.689 + }
1.690 + break;
1.691 + }
1.692 +
1.693 + case E3GPH263Profile0:
1.694 + case E3GPH263Profile3:
1.695 + {
1.696 + INFO_PRINTF1(_L("Video Type: H263"));
1.697 + T3GPVideoPropertiesH263::TProfile profile = T3GPVideoPropertiesH263::EProfile0;
1.698 + if (type == E3GPH263Profile3)
1.699 + {
1.700 + profile = T3GPVideoPropertiesH263::EProfile3;
1.701 + }
1.702 +
1.703 + TInt videoLevel;
1.704 + err = iParser->GetH263VideoLevel(videoLevel);
1.705 + if( err != KErrNone )
1.706 + {
1.707 + ERR_PRINTF1(_L("aParser->GetH263VideoLevel() failed"));
1.708 + }
1.709 + else
1.710 + {
1.711 + aProperties = new T3GPVideoPropertiesH263(timeScale, size, videoLevel, profile);
1.712 + if( !aProperties )
1.713 + {
1.714 + ERR_PRINTF1(_L("T3GPVideoPropertiesH263 allocation failed"));
1.715 + err = KErrNoMemory;
1.716 + }
1.717 + }
1.718 + break;
1.719 + }
1.720 +
1.721 + case E3GPNoVideo:
1.722 + INFO_PRINTF1(_L("Video Type: None"));
1.723 + break;
1.724 +
1.725 + default:
1.726 + err = KErrNotSupported;
1.727 + break;
1.728 + }
1.729 +
1.730 + return err;
1.731 + }
1.732 +
1.733 +TInt C3GPLibParseComposeFile::GetVideoDecoderSpecificInfo(RBuf8& aBuffer)
1.734 + {
1.735 + TInt size;
1.736 + TInt err = iParser->GetVideoDecoderSpecificInfoSize(size);
1.737 + if (err != KErrNone)
1.738 + {
1.739 + ERR_PRINTF1(_L("GetVideoDecoderSpecificInfoSize() failed"));
1.740 + return err;
1.741 + }
1.742 +
1.743 + err = aBuffer.Create(size);
1.744 + if (err != KErrNone)
1.745 + {
1.746 + ERR_PRINTF1(_L("Create buffer failed"));
1.747 + return err;
1.748 + }
1.749 +
1.750 + err = iParser->GetVideoDecoderSpecificInfo(aBuffer);
1.751 + if( err != KErrNone )
1.752 + {
1.753 + ERR_PRINTF1(_L("GetVideoDecoderSpecificInfo() failed"));
1.754 + }
1.755 +
1.756 + return err;
1.757 + }
1.758 +
1.759 +TInt C3GPLibParseComposeFile::ParseAudioProperties(C3GPParse& aParser,
1.760 + RBuf8& aAudioDecoderSpecificInfo,
1.761 + T3GPAudioPropertiesBase*& aAudioProperties,
1.762 + TUint& aLength)
1.763 + {
1.764 +
1.765 + ASSERT(iParser);
1.766 +
1.767 + T3GPAudioType type;
1.768 + TInt audioFPS;
1.769 + TUint audioAvgBitRate;
1.770 + TUint timeScale;
1.771 +
1.772 + TInt err = aParser.GetAudioProperties(type, aLength, audioFPS, audioAvgBitRate, timeScale);
1.773 + if(( err != KErrNone ) && ( err != KErrNotSupported ))
1.774 + {
1.775 + ERR_PRINTF2(_L("GetAudioProperties() failed: %d"), err);
1.776 + return err;
1.777 + }
1.778 +
1.779 + switch(type)
1.780 + {
1.781 + case E3GPMpeg4Audio:
1.782 + {
1.783 + INFO_PRINTF1(_L("Audio Type: Mpeg4"));
1.784 + err = GetAudioDecoderSpecificInfo(aAudioDecoderSpecificInfo);
1.785 + if (err == KErrNone)
1.786 + {
1.787 + aAudioProperties = new T3GPAudioPropertiesMpeg4Audio(timeScale, aAudioDecoderSpecificInfo);
1.788 + if( !aAudioProperties )
1.789 + {
1.790 + ERR_PRINTF1(_L("T3GPAudioPropertiesMpeg4Audio allocation failed"));
1.791 + err = KErrNoMemory;
1.792 + }
1.793 + }
1.794 + break;
1.795 + }
1.796 +
1.797 + case E3GPQcelp13K:
1.798 + {
1.799 + INFO_PRINTF1(_L("Audio Type: Qcelp13K"));
1.800 + T3GPQcelpStorageMode mode;
1.801 + err = iParser->GetQcelpStorageMode(mode);
1.802 + if (err != KErrNone)
1.803 + {
1.804 + ERR_PRINTF1(_L("GetQcelpStorageMode failed"));
1.805 + }
1.806 + else
1.807 + {
1.808 + if( mode == E3GPMP4AudioDescriptionBox)
1.809 + {
1.810 + err = GetAudioDecoderSpecificInfo(aAudioDecoderSpecificInfo);
1.811 + aAudioProperties = new T3GPAudioPropertiesQcelp(timeScale, audioFPS, aAudioDecoderSpecificInfo);
1.812 + }
1.813 + else
1.814 + {
1.815 + aAudioProperties = new T3GPAudioPropertiesQcelp(timeScale, audioFPS);
1.816 + }
1.817 +
1.818 + if( !aAudioProperties )
1.819 + {
1.820 + ERR_PRINTF1(_L("T3GPAudioPropertiesQcelp allocation failed"));
1.821 + err = KErrNoMemory;
1.822 + }
1.823 + }
1.824 + break;
1.825 + }
1.826 +
1.827 + case E3GPAmrNB:
1.828 + {
1.829 + INFO_PRINTF1(_L("Audio Type: AMR NB"));
1.830 + aAudioProperties = new T3GPAudioPropertiesAmr(timeScale, audioFPS, KAudioModeSet, T3GPAudioPropertiesAmr::EAmrNB);
1.831 + if( !aAudioProperties )
1.832 + {
1.833 + ERR_PRINTF1(_L("T3GPAudioPropertiesAmr allocation failed"));
1.834 + err = KErrNoMemory;
1.835 + }
1.836 + break;
1.837 + }
1.838 +
1.839 + case E3GPAmrWB:
1.840 + {
1.841 + INFO_PRINTF1(_L("Audio Type: AMR WB"));
1.842 + aAudioProperties = new T3GPAudioPropertiesAmr(timeScale, audioFPS, KAudioModeSet, T3GPAudioPropertiesAmr::EAmrWB);
1.843 + if( !aAudioProperties )
1.844 + {
1.845 + ERR_PRINTF1(_L("T3GPAudioPropertiesAmr allocation failed"));
1.846 + err = KErrNoMemory;
1.847 + }
1.848 + break;
1.849 + }
1.850 +
1.851 + case E3GPNoAudio:
1.852 + INFO_PRINTF1(_L("Audio Type: None"));
1.853 + break;
1.854 +
1.855 + default:
1.856 + INFO_PRINTF1(_L("Audio Type: Unrecognized!"));
1.857 + err = KErrNotSupported;
1.858 + break;
1.859 + }
1.860 +
1.861 + return err;
1.862 + }
1.863 +
1.864 +TInt C3GPLibParseComposeFile::ReadVideoFrame(C3GPParse& aParser,
1.865 + RBuf8& aVideoBuffer,
1.866 + TBool& aVideoKeyFrame,
1.867 + TUint& aVideoTimestampInTS,
1.868 + T3GPFrameDependencies& aDependencies)
1.869 + {
1.870 + ASSERT(iParser);
1.871 +
1.872 + // flush all data in the buffer
1.873 + aVideoBuffer.Close();
1.874 +
1.875 + TInt err = aParser.GetVideoFrameDependencies(aDependencies);
1.876 + if (err != KErrNone)
1.877 + {
1.878 + aDependencies.iDependsOn = E3GPDependencyUnknown;
1.879 + aDependencies.iIsDependedOn = E3GPDependencyUnknown;
1.880 + aDependencies.iHasRedundancy = E3GPRedundancyUnknown;
1.881 + }
1.882 +
1.883 + TUint frameSize = 0;
1.884 + err = aParser.GetVideoFrameSize(frameSize);
1.885 + if (err == KErrNone)
1.886 + {
1.887 + if (frameSize > KMaxTInt / 2)
1.888 + {
1.889 + ERR_PRINTF1(_L("Video Frame too large!"));
1.890 + err = KErrOverflow;
1.891 + }
1.892 + else
1.893 + {
1.894 + err = aVideoBuffer.Create((TInt)frameSize);
1.895 + if (err == KErrNone)
1.896 + {
1.897 + TUint videoTimestampMS = 0;
1.898 + err = aParser.ReadVideoFrame(aVideoBuffer, aVideoKeyFrame, videoTimestampMS, aVideoTimestampInTS);
1.899 + if (err == KErrNone)
1.900 + {
1.901 + if (err == KErrNotSupported)
1.902 + {
1.903 + // Not supported error is OK
1.904 + err = KErrNone;
1.905 + }
1.906 + else if (err != KErrNone)
1.907 + {
1.908 + ERR_PRINTF2(_L("GetVideoFrameDependencies failed with err = %d"), err);
1.909 + }
1.910 + }
1.911 + else
1.912 + {
1.913 + ERR_PRINTF2(_L("ReadVideoFrame failed with err = %d"), err);
1.914 + }
1.915 + }
1.916 + }
1.917 + }
1.918 + else
1.919 + {
1.920 + ERR_PRINTF2(_L("GetVideoFrameSize fails with %d"), err);
1.921 + }
1.922 +
1.923 + return err;
1.924 + }
1.925 +
1.926 +TInt C3GPLibParseComposeFile::ReadAudioFrames(C3GPParse& aParser,
1.927 + RBuf8& aBuffer,
1.928 + TInt& aFramesInSample,
1.929 + TUint& aTimestampInTS)
1.930 + {
1.931 + // flush all existing data
1.932 + aBuffer.Close();
1.933 +
1.934 + TUint size = 0;
1.935 + TInt err = aParser.GetAudioFramesSize(size);
1.936 + if (err == KErrNone)
1.937 + {
1.938 + if (size > KMaxTInt / 2)
1.939 + {
1.940 + // cannot create RBuf of size > KMaxTInt / 2
1.941 + ERR_PRINTF1(_L("Audio Frames too large!"));
1.942 + err = KErrOverflow;
1.943 + }
1.944 + else
1.945 + {
1.946 + err = aBuffer.Create((TInt)size);
1.947 + if (err == KErrNone)
1.948 + {
1.949 + TUint audioTimestampMS = 0;
1.950 + err = aParser.ReadAudioFrames(aBuffer, aFramesInSample, audioTimestampMS, aTimestampInTS);
1.951 + if (err != KErrNone)
1.952 + {
1.953 + ERR_PRINTF2(_L("ReadAudioFrames failed with err = %d"), err);
1.954 + }
1.955 + }
1.956 + }
1.957 + }
1.958 + else
1.959 + {
1.960 + ERR_PRINTF2(_L("GetAudioFramesSize failed with err = %d"), err);
1.961 + }
1.962 +
1.963 + return err;
1.964 + }
1.965 +
1.966 +TBool C3GPLibParseComposeFile::CompareInputOuputFileL(const TDesC& aInputFile)
1.967 + {
1.968 + ASSERT(iParser);
1.969 + TInt err = 0;
1.970 +
1.971 + if (iLargeFile)
1.972 + {
1.973 + iParsedFileHandle64.Close();
1.974 + err = iParsedFileHandle64.Open(iFs, aInputFile, EFileShareReadersOrWriters);
1.975 + if (err == KErrNone)
1.976 + {
1.977 + err = iParser->Open(iParsedFileHandle64);
1.978 + }
1.979 + }
1.980 + else
1.981 + {
1.982 + err = iParser->Open(aInputFile);
1.983 + }
1.984 +
1.985 + if (err != KErrNone)
1.986 + {
1.987 + ERR_PRINTF2(_L("C3GPParse 1 Open() returns %d"), err);
1.988 + User::Leave(err);
1.989 + }
1.990 +
1.991 + RBuf outputFile;
1.992 + CleanupClosePushL(outputFile);
1.993 +
1.994 + outputFile.CreateL(KMaxFileName);
1.995 + outputFile.Copy(iOutputDir);
1.996 +
1.997 + TParsePtrC parsePtr(aInputFile);
1.998 + TPtrC name = parsePtr.NameAndExt();
1.999 + outputFile.Append(parsePtr.NameAndExt());
1.1000 +
1.1001 + C3GPParse* parser2 = C3GPParse::NewL();
1.1002 + CleanupStack::PushL(parser2);
1.1003 +
1.1004 + RFile64 file2;
1.1005 + if (iLargeFile)
1.1006 + {
1.1007 + err = file2.Open(iFs, outputFile, EFileShareReadersOrWriters);
1.1008 + if (err == KErrNone)
1.1009 + {
1.1010 + err = parser2->Open(file2);
1.1011 + }
1.1012 + }
1.1013 + else
1.1014 + {
1.1015 + err = parser2->Open(outputFile);
1.1016 + }
1.1017 +
1.1018 + if (err != KErrNone)
1.1019 + {
1.1020 + ERR_PRINTF2(_L("C3GPParse 2 Open() returns %d"), err);
1.1021 + User::Leave(err);
1.1022 + }
1.1023 +
1.1024 + TBool result = EFalse;
1.1025 + if (CompareVideoPropertiesL(*iParser, *parser2))
1.1026 + {
1.1027 + if (CompareAudioPropertiesL(*iParser, *parser2))
1.1028 + {
1.1029 + if (CompareAudioVideoData(*iParser, *parser2))
1.1030 + {
1.1031 + result = ETrue;
1.1032 + }
1.1033 + else
1.1034 + {
1.1035 + ERR_PRINTF1(_L("Audio/Video Data not matching"));
1.1036 + }
1.1037 + }
1.1038 + else
1.1039 + {
1.1040 + ERR_PRINTF1(_L("Audio Properites not matching"));
1.1041 + }
1.1042 + }
1.1043 + else
1.1044 + {
1.1045 + ERR_PRINTF1(_L("Video Properites not matching"));
1.1046 + }
1.1047 +
1.1048 + parser2->Complete();
1.1049 + iParser->Complete();
1.1050 +
1.1051 + if (iLargeFile)
1.1052 + {
1.1053 + file2.Close();
1.1054 + iParsedFileHandle64.Close();
1.1055 + }
1.1056 +
1.1057 + CleanupStack::PopAndDestroy(2); // outputFile, parser2
1.1058 +
1.1059 + return result;
1.1060 + }
1.1061 +
1.1062 +TBool C3GPLibParseComposeFile::CompareVideoPropertiesL(C3GPParse& aParser1,
1.1063 + C3GPParse& aParser2)
1.1064 + {
1.1065 + //
1.1066 + // Retrieve Video Properties from Parser 1
1.1067 + //
1.1068 + T3GPVideoPropertiesBase* videoProperties1 = NULL;
1.1069 + CleanupStack::PushL(videoProperties1);
1.1070 +
1.1071 + RBuf8 videoDecoderSpecificInfo1;
1.1072 + CleanupClosePushL(videoDecoderSpecificInfo1);
1.1073 +
1.1074 + TUint videoLengthInMs1 = 0;
1.1075 +
1.1076 + TInt err1 = ParseVideoProperties(aParser1, videoDecoderSpecificInfo1, videoProperties1, videoLengthInMs1);
1.1077 + if (err1 != KErrNone && err1 != KErrNotSupported)
1.1078 + {
1.1079 + ERR_PRINTF2(_L("ParseVideoProperties 1 failed: err = %d"), err1);
1.1080 + User::Leave(err1);
1.1081 + }
1.1082 +
1.1083 + //
1.1084 + // Retrieve Video Properties from Parser 2
1.1085 + //
1.1086 + T3GPVideoPropertiesBase* videoProperties2 = NULL;
1.1087 + CleanupStack::PushL(videoProperties2);
1.1088 +
1.1089 + RBuf8 videoDecoderSpecificInfo2;
1.1090 + CleanupClosePushL(videoDecoderSpecificInfo2);
1.1091 +
1.1092 + TUint videoLengthInMs2 = 0;
1.1093 +
1.1094 + TInt err2 = ParseVideoProperties(aParser2, videoDecoderSpecificInfo2, videoProperties2, videoLengthInMs2);
1.1095 + if (err2 != KErrNone && err2 != KErrNotSupported)
1.1096 + {
1.1097 + ERR_PRINTF2(_L("ParseVideoProperties 2 failed: err = %d"), err2);
1.1098 + User::Leave(err2);
1.1099 + }
1.1100 +
1.1101 + TBool result = EFalse;
1.1102 + if (err1 == err2 && err1 != KErrNotSupported)
1.1103 + {
1.1104 + if (videoLengthInMs1 == videoLengthInMs2)
1.1105 + {
1.1106 + if (videoProperties1 && videoProperties2)
1.1107 + {
1.1108 + result = (videoProperties1->iType == videoProperties2->iType) &&
1.1109 + (videoProperties1->iSize == videoProperties2->iSize) &&
1.1110 + (videoProperties1->iTimescale == videoProperties2->iTimescale);
1.1111 +
1.1112 + if (result)
1.1113 + {
1.1114 + switch(videoProperties1->iType)
1.1115 + {
1.1116 + case E3GPMpeg4Video:
1.1117 + {
1.1118 + T3GPVideoPropertiesMpeg4Video* video1 = (T3GPVideoPropertiesMpeg4Video*)videoProperties1;
1.1119 + T3GPVideoPropertiesMpeg4Video* video2 = (T3GPVideoPropertiesMpeg4Video*)videoProperties2;
1.1120 +
1.1121 + // NOTE: Comparison of the avg bit rate is omitted. The reason is that the avg. bit
1.1122 + // rate is calculated by:
1.1123 + // video avg bit rate = stream avg bit rate - audio avg bit rate
1.1124 + // However, stream avg. bit rate is not be properly set by the 3GP composer
1.1125 + // as it is not very important. Thus leading to the video avg. bit rate
1.1126 + // retrieved from the output file to NOT match the original.
1.1127 + result = ((video1->iMaxBitRate == video2->iMaxBitRate) &&
1.1128 + //(video1->iAvgBitRate == video2->iAvgBitRate) &&
1.1129 + (video1->iDecoderSpecificInfo == video2->iDecoderSpecificInfo));
1.1130 + break;
1.1131 + }
1.1132 +
1.1133 + case E3GPAvcProfileBaseline:
1.1134 + case E3GPAvcProfileMain:
1.1135 + case E3GPAvcProfileExtended:
1.1136 + case E3GPAvcProfileHigh:
1.1137 + {
1.1138 + T3GPVideoPropertiesAvc* video1 = (T3GPVideoPropertiesAvc*)videoProperties1;
1.1139 + T3GPVideoPropertiesAvc* video2 = (T3GPVideoPropertiesAvc*)videoProperties2;
1.1140 +
1.1141 + result = (video1->iDecoderSpecificInfo == video2->iDecoderSpecificInfo);
1.1142 + break;
1.1143 + }
1.1144 +
1.1145 + case E3GPH263Profile0:
1.1146 + case E3GPH263Profile3:
1.1147 + {
1.1148 + T3GPVideoPropertiesH263* video1 = (T3GPVideoPropertiesH263*)videoProperties1;
1.1149 + T3GPVideoPropertiesH263* video2 = (T3GPVideoPropertiesH263*)videoProperties2;
1.1150 +
1.1151 + result = (video1->iVideoLevel == video2->iVideoLevel);
1.1152 + break;
1.1153 + }
1.1154 + }
1.1155 + }
1.1156 + }
1.1157 + }
1.1158 + }
1.1159 + else if (err1 == KErrNotSupported && err2 == err1)
1.1160 + {
1.1161 + result = ETrue;
1.1162 + }
1.1163 +
1.1164 + CleanupStack::PopAndDestroy(4); // videoProperties1,
1.1165 + // videoProperties2,
1.1166 + // videoDecoderSpecificInfo1,
1.1167 + // videoDecoderSpecificInfo2
1.1168 +
1.1169 + return result;
1.1170 + }
1.1171 +
1.1172 +TBool C3GPLibParseComposeFile::CompareAudioPropertiesL(C3GPParse& aParser1,
1.1173 + C3GPParse& aParser2)
1.1174 + {
1.1175 + //
1.1176 + // Retrieve Audio Properties 1
1.1177 + //
1.1178 + T3GPAudioPropertiesBase* audioProperties1 = NULL;
1.1179 + CleanupStack::PushL(audioProperties1);
1.1180 +
1.1181 + RBuf8 audioDecoderSpecificInfo1;
1.1182 + CleanupClosePushL(audioDecoderSpecificInfo1);
1.1183 +
1.1184 + TUint audioLengthInMs1 = 0;
1.1185 + TInt err1 = ParseAudioProperties(aParser1, audioDecoderSpecificInfo1, audioProperties1, audioLengthInMs1);
1.1186 + if( err1 != KErrNone && err1 != KErrNotSupported)
1.1187 + {
1.1188 + ERR_PRINTF2(_L("ParseAudioProperties failed: err = %d"), err1);
1.1189 + User::Leave(err1);
1.1190 + }
1.1191 +
1.1192 + //
1.1193 + // Retrieve Audio Properties 2
1.1194 + //
1.1195 + T3GPAudioPropertiesBase* audioProperties2 = NULL;
1.1196 + CleanupStack::PushL(audioProperties2);
1.1197 +
1.1198 + RBuf8 audioDecoderSpecificInfo2;
1.1199 + CleanupClosePushL(audioDecoderSpecificInfo2);
1.1200 +
1.1201 + TUint audioLengthInMs2 = 0;
1.1202 + TInt err2 = ParseAudioProperties(aParser2, audioDecoderSpecificInfo2, audioProperties2, audioLengthInMs2);
1.1203 + if( err2 != KErrNone && err2 != KErrNotSupported)
1.1204 + {
1.1205 + ERR_PRINTF2(_L("ParseAudioProperties failed: err = %d"), err2);
1.1206 + User::Leave(err2);
1.1207 + }
1.1208 +
1.1209 + TBool result = EFalse;
1.1210 + if (err1 == err2 && err1 != KErrNotSupported)
1.1211 + {
1.1212 + if (audioLengthInMs2 == audioLengthInMs1)
1.1213 + {
1.1214 + if (audioProperties1 && audioProperties2)
1.1215 + {
1.1216 + result = (audioProperties1->iType == audioProperties2->iType) &&
1.1217 + (audioProperties1->iFramesPerSample == audioProperties2->iFramesPerSample) &&
1.1218 + (audioProperties1->iTimescale == audioProperties2->iTimescale);
1.1219 +
1.1220 + if (result)
1.1221 + {
1.1222 + switch(audioProperties1->iType)
1.1223 + {
1.1224 + case E3GPMpeg4Audio:
1.1225 + {
1.1226 + T3GPAudioPropertiesMpeg4Audio* audio1 = (T3GPAudioPropertiesMpeg4Audio*) audioProperties1;
1.1227 + T3GPAudioPropertiesMpeg4Audio* audio2 = (T3GPAudioPropertiesMpeg4Audio*) audioProperties2;
1.1228 + result = (audio1->iDecoderSpecificInfo == audio2->iDecoderSpecificInfo);
1.1229 + }
1.1230 + break;
1.1231 +
1.1232 + case E3GPAmrNB:
1.1233 + case E3GPAmrWB:
1.1234 + {
1.1235 + T3GPAudioPropertiesAmr* audio1 = (T3GPAudioPropertiesAmr*) audioProperties1;
1.1236 + T3GPAudioPropertiesAmr* audio2 = (T3GPAudioPropertiesAmr*) audioProperties2;
1.1237 + result = (audio1->iModeSet == audio2->iModeSet);
1.1238 + }
1.1239 + break;
1.1240 +
1.1241 + case E3GPQcelp13K:
1.1242 + {
1.1243 + T3GPAudioPropertiesQcelp* audio1 = (T3GPAudioPropertiesQcelp*) audioProperties1;
1.1244 + T3GPAudioPropertiesQcelp* audio2 = (T3GPAudioPropertiesQcelp*) audioProperties2;
1.1245 + result = ((audio1->iDecoderSpecificInfo == audio2->iDecoderSpecificInfo) &&
1.1246 + (audio1->iMode == audio2->iMode));
1.1247 + }
1.1248 + break;
1.1249 + }
1.1250 + }
1.1251 + }
1.1252 + }
1.1253 + }
1.1254 + else if (err1 == KErrNotSupported && err2 == err1)
1.1255 + {
1.1256 + result = ETrue;
1.1257 + }
1.1258 +
1.1259 + CleanupStack::PopAndDestroy(4); // audioProperties1, audioProperties2, audioDecoderSpecificInfo1, audioDecoderSpecificInfo2
1.1260 +
1.1261 + return result;
1.1262 + }
1.1263 +
1.1264 +TBool C3GPLibParseComposeFile::CompareAudioVideoData(C3GPParse& aParser1, C3GPParse& aParser2)
1.1265 + {
1.1266 + T3GPFrameType frameType1;
1.1267 + T3GPFrameType frameType2;
1.1268 + TInt err1 = KErrNone;
1.1269 + TInt err2 = KErrNone;
1.1270 + TBool keepLooping = ETrue;
1.1271 + TBool result = EFalse;
1.1272 +
1.1273 + while (keepLooping)
1.1274 + {
1.1275 + err1 = aParser1.GetFrameType(frameType1);
1.1276 + err2 = aParser2.GetFrameType(frameType2);
1.1277 +
1.1278 + if (err1 != err2)
1.1279 + {
1.1280 + break;
1.1281 + }
1.1282 + else
1.1283 + {
1.1284 + if (err1 == KErrNotFound)
1.1285 + {
1.1286 + // completed looping thru all the frames
1.1287 + break;
1.1288 + }
1.1289 +
1.1290 + if (err1 != KErrNone)
1.1291 + {
1.1292 + // if the error is not KErrNotFound, something's wrong!
1.1293 + result = EFalse;
1.1294 + }
1.1295 + else if (frameType1 != frameType2)
1.1296 + {
1.1297 + result = EFalse;
1.1298 + }
1.1299 + else if (frameType1 == E3GPVideo)
1.1300 + {
1.1301 + result = CompareVideoFrame(aParser1, aParser2);
1.1302 + }
1.1303 + else if (frameType1 == E3GPAudio)
1.1304 + {
1.1305 + result = CompareAudioFrames(aParser1, aParser2);
1.1306 + }
1.1307 +
1.1308 + if (!result)
1.1309 + {
1.1310 + break;
1.1311 + }
1.1312 + }
1.1313 + }
1.1314 +
1.1315 + return result;
1.1316 + }
1.1317 +
1.1318 +TBool C3GPLibParseComposeFile::CompareVideoFrame(C3GPParse& aParser1, C3GPParse& aParser2)
1.1319 + {
1.1320 + TUint timestamp1 = 0;
1.1321 + TUint timestamp2 = 0;
1.1322 + RBuf8 buf1;
1.1323 + RBuf8 buf2;
1.1324 + TBool keyFrame1 = EFalse;
1.1325 + TBool keyFrame2 = EFalse;
1.1326 + T3GPFrameDependencies dep1;
1.1327 + T3GPFrameDependencies dep2;
1.1328 +
1.1329 + TInt err1 = ReadVideoFrame(aParser1, buf1, keyFrame1, timestamp1, dep1);
1.1330 + TInt err2 = ReadVideoFrame(aParser2, buf2, keyFrame2, timestamp2, dep2);
1.1331 +
1.1332 + TBool result = EFalse;
1.1333 + if (err1 == err2)
1.1334 + {
1.1335 + if (keyFrame1 == keyFrame2 && timestamp1 == timestamp2)
1.1336 + {
1.1337 + if (dep1.iDependsOn == dep2.iDependsOn &&
1.1338 + dep1.iHasRedundancy == dep2.iHasRedundancy &&
1.1339 + dep1.iIsDependedOn == dep2.iIsDependedOn)
1.1340 + {
1.1341 + if (buf1 == buf2)
1.1342 + {
1.1343 + result = ETrue;
1.1344 + }
1.1345 + else
1.1346 + {
1.1347 + result = EFalse;
1.1348 + }
1.1349 + }
1.1350 + else
1.1351 + {
1.1352 + result = EFalse;
1.1353 + }
1.1354 + }
1.1355 + else
1.1356 + {
1.1357 + result = EFalse;
1.1358 + }
1.1359 + }
1.1360 + else
1.1361 + {
1.1362 + result = EFalse;
1.1363 + }
1.1364 +
1.1365 + // cleanup
1.1366 + buf1.Close();
1.1367 + buf2.Close();
1.1368 +
1.1369 + return result;
1.1370 + }
1.1371 +
1.1372 +TBool C3GPLibParseComposeFile::CompareAudioFrames(C3GPParse& aParser1, C3GPParse& aParser2)
1.1373 + {
1.1374 + TInt fps1 = 0;
1.1375 + TInt fps2 = 0;
1.1376 + TUint timestamp1 = 0;
1.1377 + TUint timestamp2 = 0;
1.1378 + RBuf8 buf1;
1.1379 + RBuf8 buf2;
1.1380 +
1.1381 + TInt err1 = ReadAudioFrames(aParser1, buf1, fps1, timestamp1);
1.1382 + TInt err2 = ReadAudioFrames(aParser2, buf2, fps2, timestamp2);
1.1383 +
1.1384 + TBool result = EFalse;
1.1385 + if (err1 == err2)
1.1386 + {
1.1387 + if (fps1 == fps2 && timestamp1 == timestamp2)
1.1388 + {
1.1389 + if (buf1 == buf2)
1.1390 + {
1.1391 + result = ETrue;
1.1392 + }
1.1393 + else
1.1394 + {
1.1395 + result = EFalse;
1.1396 + }
1.1397 + }
1.1398 + else
1.1399 + {
1.1400 + result = EFalse;
1.1401 + }
1.1402 + }
1.1403 + else
1.1404 + {
1.1405 + result = EFalse;
1.1406 + }
1.1407 +
1.1408 + // cleanup
1.1409 + buf1.Close();
1.1410 + buf2.Close();
1.1411 +
1.1412 + return result;
1.1413 + }