First public contribution.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "tsu_3gplibrary_parse_compose.h"
18 const TUint16 KAudioModeSet = 0x81ff;
19 const TReal KMillisecondsInSecond = 1000;
20 const TReal KOneHalf = 0.5;
21 const TInt KLargeFileWriteBufferSize = 16384; // 16K
22 const TInt KLargeFileWriteBufferMaxCount = 15;
24 _LIT( KAvcBaseline, "Baseline" );
25 _LIT( KAvcMain, "Main" );
26 _LIT( KAvcExtended, "Extended" );
27 _LIT( KAvcHigh, "High" );
29 const static TDesC* KAvcProfileNames[] = {
37 C3GPLibParseComposeFile::C3GPLibParseComposeFile() :
38 iCompareOriginal(EFalse),
43 TVerdict C3GPLibParseComposeFile::doTestStepPreambleL()
46 _LIT(KInputDir, "inputDirEmul");
47 _LIT(KOutputDir, "outputDirEmul");
49 _LIT(KInputDir, "inputDirHw");
50 _LIT(KOutputDir, "outputDirHw");
52 // ensure test always starts with clean results
53 SetTestStepResult(EPass);
54 SetTestStepError(KErrNone);
56 // ensure there's always a Active Scheduler for the Composer
57 if (!CActiveScheduler::Current())
59 iScheduler = new (ELeave) CActiveScheduler;
60 CActiveScheduler::Install(iScheduler);
63 User::LeaveIfError(iFs.Connect());
64 // retrieve the input files' directory
66 TBool composeFile = EFalse;
68 if (GetStringFromConfig(ConfigSection(), KInputDir, inputFileDir))
70 if (inputFileDir.Length() == 0)
72 ERR_PRINTF1(_L("Ensure input directory is specified."));
73 SetTestStepResult(EInconclusive);
74 return TestStepResult();
78 iInputDir.CreateL(inputFileDir);
81 GetIntFromConfig(ConfigSection(), _L("expectedFailure"), iExpectedNumberOfFailure);
83 if (GetBoolFromConfig(ConfigSection(), _L("composeFile"), composeFile))
87 if (GetStringFromConfig(ConfigSection(), KOutputDir, outputFileDir))
89 if (outputFileDir.Length() == 0)
91 ERR_PRINTF1(_L("Ensure output directory is specified."));
92 SetTestStepResult(EInconclusive);
93 return TestStepResult();
95 else if (outputFileDir == inputFileDir)
97 ERR_PRINTF1(_L("Ensure output directory is not the same as input directory."));
98 SetTestStepResult(EInconclusive);
99 return TestStepResult();
101 else if (!GetIntFromConfig(ConfigSection(), _L("fileFormat"), iFileFormat))
103 ERR_PRINTF1(_L("Ensure a output file format is specified."));
104 SetTestStepResult(EInconclusive);
105 return TestStepResult();
108 GetIntFromConfig(ConfigSection(), _L("composeFlag"), iComposeFlag);
109 GetBoolFromConfig(ConfigSection(), _L("compareOriginal"), iCompareOriginal);
110 GetBoolFromConfig(ConfigSection(), _L("largeFile"), iLargeFile);
114 ERR_PRINTF1(_L("Ensure output directory is specified."));
115 SetTestStepResult(EInconclusive);
122 ERR_PRINTF1(_L("Ensure input directory is specified."));
123 SetTestStepResult(EInconclusive);
126 if (TestStepResult() == EPass)
128 // Create a list of all files contained in the input directory
129 User::LeaveIfError(iFs.GetDir(inputFileDir, KEntryAttNormal, ESortNone, iDirList));
131 if (!iDirList || iDirList->Count() == 0)
133 ERR_PRINTF1(_L("Input directory is empty."));
134 SetTestStepResult(EInconclusive);
138 if (TestStepResult() == EPass)
140 iParser = C3GPParse::NewL();
145 iComposer = C3GPCompose::NewL(KLargeFileWriteBufferSize, KLargeFileWriteBufferMaxCount);
149 iComposer = C3GPCompose::NewL();
152 iOutputDir.CreateL(outputFileDir);
153 TInt err = iFs.MkDirAll(iOutputDir);
154 if (err != KErrNone && err != KErrAlreadyExists)
161 return TestStepResult();
164 TVerdict C3GPLibParseComposeFile::doTestStepL()
166 if( TestStepResult() == EPass)
171 CleanupClosePushL(filePath);
172 filePath.CreateL(KMaxFileName);
174 for (TInt i = 0; i < iDirList->Count(); i++)
176 const TEntry& entry = (*iDirList)[i];
181 filePath.Copy(iInputDir);
182 filePath.Append(entry.iName);
184 INFO_PRINTF2(_L("ParseAndComposeL: file=%S"), &filePath);
185 TRAPD(err, ParseFileL(filePath));
186 INFO_PRINTF2(_L("ParseAndComposeL returns: err = %d"), err);
187 if( err != KErrNone )
192 iComposer->Complete();
198 if (iCompareOriginal && iComposer)
200 if (!CompareInputOuputFileL(filePath))
202 ERR_PRINTF1(_L("Input & output file is not the same"));
207 INFO_PRINTF1(_L("Input & output file is the same."));
215 CleanupStack::PopAndDestroy(&filePath);
217 INFO_PRINTF3(_L("%d of %d files failed"), failCount, fileCount);
218 if (failCount != iExpectedNumberOfFailure)
220 ERR_PRINTF2(_L("Expected failure: %d - Test Failed"), iExpectedNumberOfFailure);
221 SetTestStepResult(EFail);
225 return TestStepResult();
228 TVerdict C3GPLibParseComposeFile::doTestStepPostambleL()
232 CActiveScheduler::Install(NULL);
238 iComposedFile.Close();
242 iParsedFileHandle64.Close();
243 iComposedFileHandle64.Close();
252 return TestStepResult();
255 void C3GPLibParseComposeFile::ParseFileL(const TDesC& aInputFile)
262 iParsedFileHandle64.Close();
263 err = iParsedFileHandle64.Open(iFs, aInputFile, EFileShareReadersOrWriters);
266 err = iParser->Open(iParsedFileHandle64);
271 err = iParser->Open(aInputFile);
276 ERR_PRINTF2(_L("C3GPParse::Open() returns %d"), err);
281 // Retrieve Video Properties
283 T3GPVideoPropertiesBase* videoProperties = NULL;
284 CleanupStack::PushL(videoProperties);
286 RBuf8 videoDecoderSpecificInfo;
287 CleanupClosePushL(videoDecoderSpecificInfo);
289 TUint videoLengthInMs = 0;
291 err = ParseVideoProperties(*iParser, videoDecoderSpecificInfo, videoProperties, videoLengthInMs);
292 if (err != KErrNone && err != KErrNotSupported)
294 ERR_PRINTF2(_L("ParseVideoProperties failed: err = %d"), err);
299 // Retrieve Audio Properties
301 T3GPAudioPropertiesBase* audioProperties = NULL;
302 CleanupStack::PushL(audioProperties);
304 RBuf8 audioDecoderSpecificInfo;
305 CleanupClosePushL(audioDecoderSpecificInfo);
307 TUint audioLengthInMs = 0;
308 err = ParseAudioProperties(*iParser, audioDecoderSpecificInfo, audioProperties, audioLengthInMs);
309 if( err != KErrNone && err != KErrNotSupported)
311 ERR_PRINTF2(_L("ParseAudioProperties failed: err = %d"), err);
315 if (!videoProperties && !audioProperties)
317 ERR_PRINTF1(_L("File contains neither video nor audio data"));
318 User::Leave(KErrNotFound);
322 // Prepare for the Composer if file output is expected
327 CleanupClosePushL(outputFile);
329 outputFile.CreateL(KMaxFileName);
330 outputFile.Copy(iOutputDir);
332 TParsePtrC parsePtr(aInputFile);
333 TPtrC name = parsePtr.NameAndExt();
335 outputFile.Append(parsePtr.NameAndExt());
339 iComposedFileHandle64.Close();
340 err = iComposedFileHandle64.Create(iFs, outputFile, EFileShareAny|EFileStream|EFileWrite);
341 if (err == KErrAlreadyExists)
343 err = iComposedFileHandle64.Replace(iFs, outputFile, EFileShareAny|EFileStream|EFileWrite);
348 err = iComposer->Open((T3GPFileFormatType)iFileFormat, videoProperties, audioProperties, iComposedFileHandle64, iComposeFlag);
353 err = iComposer->Open((T3GPFileFormatType)iFileFormat, videoProperties, audioProperties, outputFile, iComposeFlag);
358 ERR_PRINTF2(_L("C3GPCompose::Open failed: err = %d"), err);
362 CleanupStack::PopAndDestroy(&outputFile);
366 // Parse and compose (if specified) video / audio frame data
368 ReadWriteAudioVideoFramesL(videoProperties, audioProperties, videoLengthInMs, audioLengthInMs);
373 CleanupStack::PopAndDestroy(4);
374 // audioDecoderSpecificInfo
376 // videoDecoderSpecificInfo
381 err = iComposer->Complete();
384 ERR_PRINTF1(_L("aComposer->Complete() failed"));
390 iComposedFileHandle64.Close();
394 err = iParser->Complete();
397 ERR_PRINTF1(_L("aParser->Complete() failed"));
403 iParsedFileHandle64.Close();
406 INFO_PRINTF1(_L("C3GPLibParseComposeFile::ParseAndComposeL OUT"));
409 void C3GPLibParseComposeFile::ReadWriteAudioVideoFramesL(const T3GPVideoPropertiesBase* aVideoProperties,
410 const T3GPAudioPropertiesBase* aAudioProperties,
411 TUint aVideoLengthInMs,
412 TUint aAudioLengthInMs)
416 TUint videoLengthInTS = 0;
417 TUint audioLengthInTS = 0;
418 if (aVideoProperties)
420 // The "+KOneHalf" in the following calculation has the effect of rounding
421 // to the nearest integer instead of just flooring it when converting from
423 // This is to avoid videoLengthInTS being off by one and leading to false
424 // positives when the video properties are compared later on.
425 videoLengthInTS = (TUint) ((TReal)(aVideoLengthInMs * aVideoProperties->iTimescale) / KMillisecondsInSecond + KOneHalf );
427 if (aAudioProperties)
429 // The "+KOneHalf" in the following calculation has the effect of rounding
430 // to the nearest integer instead of just flooring it when converting from
432 // This is to avoid audioLengthInTS being off by one and leading to false
433 // positives when the audio properties are compared later on.
434 audioLengthInTS = (TUint) ((TReal)(aAudioLengthInMs * aAudioProperties->iTimescale) / KMillisecondsInSecond + KOneHalf );
437 TInt framePerSample1 = 0;
438 TInt framePerSample2 = 0;
443 CleanupClosePushL(audioBuf1);
444 CleanupClosePushL(audioBuf2);
450 T3GPFrameDependencies dep1;
451 T3GPFrameDependencies dep2;
454 CleanupClosePushL(videoBuf1);
455 CleanupClosePushL(videoBuf2);
458 T3GPFrameType frameType;
460 RArray<T3GPFrameType> frameTypeArray(10);
461 CleanupClosePushL(frameTypeArray);
463 TInt videoFrameCount = 0;
464 TInt audioFrameCount = 0;
466 while (err == KErrNone)
468 err = iParser->GetFrameType(frameType);
475 frameTypeArray.AppendL(frameType);
476 err = ReadAudioFrames(*iParser, audioBuf1, framePerSample1, audioTS1);
482 frameTypeArray.AppendL(frameType);
483 err = ReadVideoFrame(*iParser, videoBuf1, keyFrame1, videoTS1, dep1);
488 ERR_PRINTF1(_L("GetFrameType retrieves an unsupported frame type"));
489 User::Leave(KErrUnknown);
493 // if there's anything wrong w/ retrieving the frame, exit the function now
494 User::LeaveIfError(err);
498 INFO_PRINTF2(_L("ReadWriteAudioVideoFramesL read %d video frames."), videoFrameCount);
499 INFO_PRINTF2(_L("ReadWriteAudioVideoFramesL read %d audio frames."), audioFrameCount);
501 // reset the video and audio cursor at the beginning of the clip
504 iParser->Seek(0, EFalse, videoPos, audioPos);
511 // if the data should be supplied into a composer to construct an output file
513 while (index < frameTypeArray.Count())
515 frameType = frameTypeArray[index++];
519 if (audioBuf1.Length() == 0)
521 User::LeaveIfError(ReadAudioFrames(*iParser, audioBuf1, framePerSample1, audioTS1));
523 err = ReadAudioFrames(*iParser, audioBuf2, framePerSample2, audioTS2);
525 if (audioBuf1.Length() > 0 && audioBuf2.Length() > 0 ||
526 audioBuf1.Length() > 0 && err == KErrNotFound)
529 if (audioBuf2.Length() == 0)
531 // duration for the last batch of audio frames = total audio length - the 2nd last audio frame
532 duration = audioLengthInTS - audioTS1;
536 duration = audioTS2 - audioTS1;
539 User::LeaveIfError(iComposer->WriteAudioFrames(audioBuf1, duration));
543 audioBuf1.Swap(audioBuf2);
544 framePerSample1 = framePerSample2;
550 if (videoBuf1.Length() == 0)
552 User::LeaveIfError(ReadVideoFrame(*iParser, videoBuf1, keyFrame1, videoTS1, dep1));
554 err = ReadVideoFrame(*iParser, videoBuf2, keyFrame2, videoTS2, dep2);
556 if (videoBuf1.Length() > 0 && videoBuf2.Length() > 0 ||
557 videoBuf1.Length() > 0 && err == KErrNotFound)
560 if (videoBuf2.Length() == 0)
562 // duration for the last batch of audio frames = total audio length - the 2nd last audio frame
563 duration = videoLengthInTS - videoTS1;
567 duration = videoTS2 - videoTS1;
570 User::LeaveIfError(iComposer->WriteVideoFrame(videoBuf1, duration, keyFrame1, dep1));
574 videoBuf1.Swap(videoBuf2);
575 keyFrame1 = keyFrame2;
577 dep1.iDependsOn = dep2.iDependsOn;
578 dep1.iIsDependedOn = dep2.iIsDependedOn;
579 dep1.iHasRedundancy = dep2.iHasRedundancy;
584 ERR_PRINTF1(_L("Unknown frame type detected."));
585 User::Leave(KErrUnknown);
588 } // end of while loop
591 CleanupStack::PopAndDestroy(5);
593 INFO_PRINTF2(_L("ReadWriteAudioVideoFramesL wrote %d video frames."), videoFrameCount);
594 INFO_PRINTF2(_L("ReadWriteAudioVideoFramesL wrote %d audio frames."), audioFrameCount);
597 TInt C3GPLibParseComposeFile::GetAudioDecoderSpecificInfo(RBuf8& aBuffer)
602 TInt err = iParser->GetAudioDecoderSpecificInfoSize(size);
603 if( err != KErrNone )
605 ERR_PRINTF2(_L("GetAudioDecoderSpecificInfoSize() failed: %d"), err);
609 err = aBuffer.Create(size);
610 if( err != KErrNone )
612 ERR_PRINTF1(_L("Create buffer failed"));
616 err = iParser->GetAudioDecoderSpecificInfo(aBuffer);
617 if( err != KErrNone )
619 ERR_PRINTF2(_L("GetAudioDecoderSpecificInfo() failed: %d"), err);
625 TInt C3GPLibParseComposeFile::ParseVideoProperties(C3GPParse& aParser,
626 RBuf8& aDecoderSpecificInfo,
627 T3GPVideoPropertiesBase*& aProperties,
638 TInt err = aParser.GetVideoProperties(type, aLengthInMs, frameRate, avgBitRate, size, timeScale);
639 if ((err != KErrNone) && (err != KErrNotSupported))
641 ERR_PRINTF2(_L("aParser->GetVideoProperties failed: %d"), err);
649 INFO_PRINTF1(_L("Video Type: Mpeg4"));
650 err = GetVideoDecoderSpecificInfo(aDecoderSpecificInfo);
653 aProperties = new T3GPVideoPropertiesMpeg4Video(timeScale, size,
654 64000, avgBitRate, aDecoderSpecificInfo);
657 ERR_PRINTF1(_L("T3GPVideoPropertiesMpeg4Video allocation failed"));
664 case E3GPAvcProfileBaseline:
665 case E3GPAvcProfileMain:
666 case E3GPAvcProfileExtended:
667 case E3GPAvcProfileHigh:
669 err = GetVideoDecoderSpecificInfo(aDecoderSpecificInfo);
672 INFO_PRINTF2(_L("Video Type: Avc Profile %S"), KAvcProfileNames[type-E3GPAvcProfileBaseline] );
673 aProperties = new T3GPVideoPropertiesAvc(timeScale, size, aDecoderSpecificInfo);
676 ERR_PRINTF1(_L("T3GPVideoPropertiesAvc allocation failed"));
681 // T3GPVideoPropertiesAvc defaults the video type to AVC baseline profile.
682 // Need to override that here because we want to check for the specific
683 // profile in this test.
684 aProperties->iType = type;
690 case E3GPH263Profile0:
691 case E3GPH263Profile3:
693 INFO_PRINTF1(_L("Video Type: H263"));
694 T3GPVideoPropertiesH263::TProfile profile = T3GPVideoPropertiesH263::EProfile0;
695 if (type == E3GPH263Profile3)
697 profile = T3GPVideoPropertiesH263::EProfile3;
701 err = iParser->GetH263VideoLevel(videoLevel);
702 if( err != KErrNone )
704 ERR_PRINTF1(_L("aParser->GetH263VideoLevel() failed"));
708 aProperties = new T3GPVideoPropertiesH263(timeScale, size, videoLevel, profile);
711 ERR_PRINTF1(_L("T3GPVideoPropertiesH263 allocation failed"));
719 INFO_PRINTF1(_L("Video Type: None"));
723 err = KErrNotSupported;
730 TInt C3GPLibParseComposeFile::GetVideoDecoderSpecificInfo(RBuf8& aBuffer)
733 TInt err = iParser->GetVideoDecoderSpecificInfoSize(size);
736 ERR_PRINTF1(_L("GetVideoDecoderSpecificInfoSize() failed"));
740 err = aBuffer.Create(size);
743 ERR_PRINTF1(_L("Create buffer failed"));
747 err = iParser->GetVideoDecoderSpecificInfo(aBuffer);
748 if( err != KErrNone )
750 ERR_PRINTF1(_L("GetVideoDecoderSpecificInfo() failed"));
756 TInt C3GPLibParseComposeFile::ParseAudioProperties(C3GPParse& aParser,
757 RBuf8& aAudioDecoderSpecificInfo,
758 T3GPAudioPropertiesBase*& aAudioProperties,
766 TUint audioAvgBitRate;
769 TInt err = aParser.GetAudioProperties(type, aLength, audioFPS, audioAvgBitRate, timeScale);
770 if(( err != KErrNone ) && ( err != KErrNotSupported ))
772 ERR_PRINTF2(_L("GetAudioProperties() failed: %d"), err);
780 INFO_PRINTF1(_L("Audio Type: Mpeg4"));
781 err = GetAudioDecoderSpecificInfo(aAudioDecoderSpecificInfo);
784 aAudioProperties = new T3GPAudioPropertiesMpeg4Audio(timeScale, aAudioDecoderSpecificInfo);
785 if( !aAudioProperties )
787 ERR_PRINTF1(_L("T3GPAudioPropertiesMpeg4Audio allocation failed"));
796 INFO_PRINTF1(_L("Audio Type: Qcelp13K"));
797 T3GPQcelpStorageMode mode;
798 err = iParser->GetQcelpStorageMode(mode);
801 ERR_PRINTF1(_L("GetQcelpStorageMode failed"));
805 if( mode == E3GPMP4AudioDescriptionBox)
807 err = GetAudioDecoderSpecificInfo(aAudioDecoderSpecificInfo);
808 aAudioProperties = new T3GPAudioPropertiesQcelp(timeScale, audioFPS, aAudioDecoderSpecificInfo);
812 aAudioProperties = new T3GPAudioPropertiesQcelp(timeScale, audioFPS);
815 if( !aAudioProperties )
817 ERR_PRINTF1(_L("T3GPAudioPropertiesQcelp allocation failed"));
826 INFO_PRINTF1(_L("Audio Type: AMR NB"));
827 aAudioProperties = new T3GPAudioPropertiesAmr(timeScale, audioFPS, KAudioModeSet, T3GPAudioPropertiesAmr::EAmrNB);
828 if( !aAudioProperties )
830 ERR_PRINTF1(_L("T3GPAudioPropertiesAmr allocation failed"));
838 INFO_PRINTF1(_L("Audio Type: AMR WB"));
839 aAudioProperties = new T3GPAudioPropertiesAmr(timeScale, audioFPS, KAudioModeSet, T3GPAudioPropertiesAmr::EAmrWB);
840 if( !aAudioProperties )
842 ERR_PRINTF1(_L("T3GPAudioPropertiesAmr allocation failed"));
849 INFO_PRINTF1(_L("Audio Type: None"));
853 INFO_PRINTF1(_L("Audio Type: Unrecognized!"));
854 err = KErrNotSupported;
861 TInt C3GPLibParseComposeFile::ReadVideoFrame(C3GPParse& aParser,
863 TBool& aVideoKeyFrame,
864 TUint& aVideoTimestampInTS,
865 T3GPFrameDependencies& aDependencies)
869 // flush all data in the buffer
870 aVideoBuffer.Close();
872 TInt err = aParser.GetVideoFrameDependencies(aDependencies);
875 aDependencies.iDependsOn = E3GPDependencyUnknown;
876 aDependencies.iIsDependedOn = E3GPDependencyUnknown;
877 aDependencies.iHasRedundancy = E3GPRedundancyUnknown;
881 err = aParser.GetVideoFrameSize(frameSize);
884 if (frameSize > KMaxTInt / 2)
886 ERR_PRINTF1(_L("Video Frame too large!"));
891 err = aVideoBuffer.Create((TInt)frameSize);
894 TUint videoTimestampMS = 0;
895 err = aParser.ReadVideoFrame(aVideoBuffer, aVideoKeyFrame, videoTimestampMS, aVideoTimestampInTS);
898 if (err == KErrNotSupported)
900 // Not supported error is OK
903 else if (err != KErrNone)
905 ERR_PRINTF2(_L("GetVideoFrameDependencies failed with err = %d"), err);
910 ERR_PRINTF2(_L("ReadVideoFrame failed with err = %d"), err);
917 ERR_PRINTF2(_L("GetVideoFrameSize fails with %d"), err);
923 TInt C3GPLibParseComposeFile::ReadAudioFrames(C3GPParse& aParser,
925 TInt& aFramesInSample,
926 TUint& aTimestampInTS)
928 // flush all existing data
932 TInt err = aParser.GetAudioFramesSize(size);
935 if (size > KMaxTInt / 2)
937 // cannot create RBuf of size > KMaxTInt / 2
938 ERR_PRINTF1(_L("Audio Frames too large!"));
943 err = aBuffer.Create((TInt)size);
946 TUint audioTimestampMS = 0;
947 err = aParser.ReadAudioFrames(aBuffer, aFramesInSample, audioTimestampMS, aTimestampInTS);
950 ERR_PRINTF2(_L("ReadAudioFrames failed with err = %d"), err);
957 ERR_PRINTF2(_L("GetAudioFramesSize failed with err = %d"), err);
963 TBool C3GPLibParseComposeFile::CompareInputOuputFileL(const TDesC& aInputFile)
970 iParsedFileHandle64.Close();
971 err = iParsedFileHandle64.Open(iFs, aInputFile, EFileShareReadersOrWriters);
974 err = iParser->Open(iParsedFileHandle64);
979 err = iParser->Open(aInputFile);
984 ERR_PRINTF2(_L("C3GPParse 1 Open() returns %d"), err);
989 CleanupClosePushL(outputFile);
991 outputFile.CreateL(KMaxFileName);
992 outputFile.Copy(iOutputDir);
994 TParsePtrC parsePtr(aInputFile);
995 TPtrC name = parsePtr.NameAndExt();
996 outputFile.Append(parsePtr.NameAndExt());
998 C3GPParse* parser2 = C3GPParse::NewL();
999 CleanupStack::PushL(parser2);
1004 err = file2.Open(iFs, outputFile, EFileShareReadersOrWriters);
1005 if (err == KErrNone)
1007 err = parser2->Open(file2);
1012 err = parser2->Open(outputFile);
1015 if (err != KErrNone)
1017 ERR_PRINTF2(_L("C3GPParse 2 Open() returns %d"), err);
1021 TBool result = EFalse;
1022 if (CompareVideoPropertiesL(*iParser, *parser2))
1024 if (CompareAudioPropertiesL(*iParser, *parser2))
1026 if (CompareAudioVideoData(*iParser, *parser2))
1032 ERR_PRINTF1(_L("Audio/Video Data not matching"));
1037 ERR_PRINTF1(_L("Audio Properites not matching"));
1042 ERR_PRINTF1(_L("Video Properites not matching"));
1045 parser2->Complete();
1046 iParser->Complete();
1051 iParsedFileHandle64.Close();
1054 CleanupStack::PopAndDestroy(2); // outputFile, parser2
1059 TBool C3GPLibParseComposeFile::CompareVideoPropertiesL(C3GPParse& aParser1,
1060 C3GPParse& aParser2)
1063 // Retrieve Video Properties from Parser 1
1065 T3GPVideoPropertiesBase* videoProperties1 = NULL;
1066 CleanupStack::PushL(videoProperties1);
1068 RBuf8 videoDecoderSpecificInfo1;
1069 CleanupClosePushL(videoDecoderSpecificInfo1);
1071 TUint videoLengthInMs1 = 0;
1073 TInt err1 = ParseVideoProperties(aParser1, videoDecoderSpecificInfo1, videoProperties1, videoLengthInMs1);
1074 if (err1 != KErrNone && err1 != KErrNotSupported)
1076 ERR_PRINTF2(_L("ParseVideoProperties 1 failed: err = %d"), err1);
1081 // Retrieve Video Properties from Parser 2
1083 T3GPVideoPropertiesBase* videoProperties2 = NULL;
1084 CleanupStack::PushL(videoProperties2);
1086 RBuf8 videoDecoderSpecificInfo2;
1087 CleanupClosePushL(videoDecoderSpecificInfo2);
1089 TUint videoLengthInMs2 = 0;
1091 TInt err2 = ParseVideoProperties(aParser2, videoDecoderSpecificInfo2, videoProperties2, videoLengthInMs2);
1092 if (err2 != KErrNone && err2 != KErrNotSupported)
1094 ERR_PRINTF2(_L("ParseVideoProperties 2 failed: err = %d"), err2);
1098 TBool result = EFalse;
1099 if (err1 == err2 && err1 != KErrNotSupported)
1101 if (videoLengthInMs1 == videoLengthInMs2)
1103 if (videoProperties1 && videoProperties2)
1105 result = (videoProperties1->iType == videoProperties2->iType) &&
1106 (videoProperties1->iSize == videoProperties2->iSize) &&
1107 (videoProperties1->iTimescale == videoProperties2->iTimescale);
1111 switch(videoProperties1->iType)
1113 case E3GPMpeg4Video:
1115 T3GPVideoPropertiesMpeg4Video* video1 = (T3GPVideoPropertiesMpeg4Video*)videoProperties1;
1116 T3GPVideoPropertiesMpeg4Video* video2 = (T3GPVideoPropertiesMpeg4Video*)videoProperties2;
1118 // NOTE: Comparison of the avg bit rate is omitted. The reason is that the avg. bit
1119 // rate is calculated by:
1120 // video avg bit rate = stream avg bit rate - audio avg bit rate
1121 // However, stream avg. bit rate is not be properly set by the 3GP composer
1122 // as it is not very important. Thus leading to the video avg. bit rate
1123 // retrieved from the output file to NOT match the original.
1124 result = ((video1->iMaxBitRate == video2->iMaxBitRate) &&
1125 //(video1->iAvgBitRate == video2->iAvgBitRate) &&
1126 (video1->iDecoderSpecificInfo == video2->iDecoderSpecificInfo));
1130 case E3GPAvcProfileBaseline:
1131 case E3GPAvcProfileMain:
1132 case E3GPAvcProfileExtended:
1133 case E3GPAvcProfileHigh:
1135 T3GPVideoPropertiesAvc* video1 = (T3GPVideoPropertiesAvc*)videoProperties1;
1136 T3GPVideoPropertiesAvc* video2 = (T3GPVideoPropertiesAvc*)videoProperties2;
1138 result = (video1->iDecoderSpecificInfo == video2->iDecoderSpecificInfo);
1142 case E3GPH263Profile0:
1143 case E3GPH263Profile3:
1145 T3GPVideoPropertiesH263* video1 = (T3GPVideoPropertiesH263*)videoProperties1;
1146 T3GPVideoPropertiesH263* video2 = (T3GPVideoPropertiesH263*)videoProperties2;
1148 result = (video1->iVideoLevel == video2->iVideoLevel);
1156 else if (err1 == KErrNotSupported && err2 == err1)
1161 CleanupStack::PopAndDestroy(4); // videoProperties1,
1162 // videoProperties2,
1163 // videoDecoderSpecificInfo1,
1164 // videoDecoderSpecificInfo2
1169 TBool C3GPLibParseComposeFile::CompareAudioPropertiesL(C3GPParse& aParser1,
1170 C3GPParse& aParser2)
1173 // Retrieve Audio Properties 1
1175 T3GPAudioPropertiesBase* audioProperties1 = NULL;
1176 CleanupStack::PushL(audioProperties1);
1178 RBuf8 audioDecoderSpecificInfo1;
1179 CleanupClosePushL(audioDecoderSpecificInfo1);
1181 TUint audioLengthInMs1 = 0;
1182 TInt err1 = ParseAudioProperties(aParser1, audioDecoderSpecificInfo1, audioProperties1, audioLengthInMs1);
1183 if( err1 != KErrNone && err1 != KErrNotSupported)
1185 ERR_PRINTF2(_L("ParseAudioProperties failed: err = %d"), err1);
1190 // Retrieve Audio Properties 2
1192 T3GPAudioPropertiesBase* audioProperties2 = NULL;
1193 CleanupStack::PushL(audioProperties2);
1195 RBuf8 audioDecoderSpecificInfo2;
1196 CleanupClosePushL(audioDecoderSpecificInfo2);
1198 TUint audioLengthInMs2 = 0;
1199 TInt err2 = ParseAudioProperties(aParser2, audioDecoderSpecificInfo2, audioProperties2, audioLengthInMs2);
1200 if( err2 != KErrNone && err2 != KErrNotSupported)
1202 ERR_PRINTF2(_L("ParseAudioProperties failed: err = %d"), err2);
1206 TBool result = EFalse;
1207 if (err1 == err2 && err1 != KErrNotSupported)
1209 if (audioLengthInMs2 == audioLengthInMs1)
1211 if (audioProperties1 && audioProperties2)
1213 result = (audioProperties1->iType == audioProperties2->iType) &&
1214 (audioProperties1->iFramesPerSample == audioProperties2->iFramesPerSample) &&
1215 (audioProperties1->iTimescale == audioProperties2->iTimescale);
1219 switch(audioProperties1->iType)
1221 case E3GPMpeg4Audio:
1223 T3GPAudioPropertiesMpeg4Audio* audio1 = (T3GPAudioPropertiesMpeg4Audio*) audioProperties1;
1224 T3GPAudioPropertiesMpeg4Audio* audio2 = (T3GPAudioPropertiesMpeg4Audio*) audioProperties2;
1225 result = (audio1->iDecoderSpecificInfo == audio2->iDecoderSpecificInfo);
1232 T3GPAudioPropertiesAmr* audio1 = (T3GPAudioPropertiesAmr*) audioProperties1;
1233 T3GPAudioPropertiesAmr* audio2 = (T3GPAudioPropertiesAmr*) audioProperties2;
1234 result = (audio1->iModeSet == audio2->iModeSet);
1240 T3GPAudioPropertiesQcelp* audio1 = (T3GPAudioPropertiesQcelp*) audioProperties1;
1241 T3GPAudioPropertiesQcelp* audio2 = (T3GPAudioPropertiesQcelp*) audioProperties2;
1242 result = ((audio1->iDecoderSpecificInfo == audio2->iDecoderSpecificInfo) &&
1243 (audio1->iMode == audio2->iMode));
1251 else if (err1 == KErrNotSupported && err2 == err1)
1256 CleanupStack::PopAndDestroy(4); // audioProperties1, audioProperties2, audioDecoderSpecificInfo1, audioDecoderSpecificInfo2
1261 TBool C3GPLibParseComposeFile::CompareAudioVideoData(C3GPParse& aParser1, C3GPParse& aParser2)
1263 T3GPFrameType frameType1;
1264 T3GPFrameType frameType2;
1265 TInt err1 = KErrNone;
1266 TInt err2 = KErrNone;
1267 TBool keepLooping = ETrue;
1268 TBool result = EFalse;
1272 err1 = aParser1.GetFrameType(frameType1);
1273 err2 = aParser2.GetFrameType(frameType2);
1281 if (err1 == KErrNotFound)
1283 // completed looping thru all the frames
1287 if (err1 != KErrNone)
1289 // if the error is not KErrNotFound, something's wrong!
1292 else if (frameType1 != frameType2)
1296 else if (frameType1 == E3GPVideo)
1298 result = CompareVideoFrame(aParser1, aParser2);
1300 else if (frameType1 == E3GPAudio)
1302 result = CompareAudioFrames(aParser1, aParser2);
1315 TBool C3GPLibParseComposeFile::CompareVideoFrame(C3GPParse& aParser1, C3GPParse& aParser2)
1317 TUint timestamp1 = 0;
1318 TUint timestamp2 = 0;
1321 TBool keyFrame1 = EFalse;
1322 TBool keyFrame2 = EFalse;
1323 T3GPFrameDependencies dep1;
1324 T3GPFrameDependencies dep2;
1326 TInt err1 = ReadVideoFrame(aParser1, buf1, keyFrame1, timestamp1, dep1);
1327 TInt err2 = ReadVideoFrame(aParser2, buf2, keyFrame2, timestamp2, dep2);
1329 TBool result = EFalse;
1332 if (keyFrame1 == keyFrame2 && timestamp1 == timestamp2)
1334 if (dep1.iDependsOn == dep2.iDependsOn &&
1335 dep1.iHasRedundancy == dep2.iHasRedundancy &&
1336 dep1.iIsDependedOn == dep2.iIsDependedOn)
1369 TBool C3GPLibParseComposeFile::CompareAudioFrames(C3GPParse& aParser1, C3GPParse& aParser2)
1373 TUint timestamp1 = 0;
1374 TUint timestamp2 = 0;
1378 TInt err1 = ReadAudioFrames(aParser1, buf1, fps1, timestamp1);
1379 TInt err2 = ReadAudioFrames(aParser2, buf2, fps2, timestamp2);
1381 TBool result = EFalse;
1384 if (fps1 == fps2 && timestamp1 == timestamp2)