diff -r 000000000000 -r 951a5db380a0 videoeditorengine/vedengine/src/VedMovieImp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoeditorengine/vedengine/src/VedMovieImp.cpp Fri Jan 29 14:08:33 2010 +0200 @@ -0,0 +1,3762 @@ +/* +* Copyright (c) 2010 Ixonos Plc. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the "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: +* Ixonos Plc +* +* Description: +* +*/ + + + + +#include "VedMovieImp.h" +#include "VedVideoClipGenerator.h" +#include "movieprocessor.h" +#include "VedVideosettings.h" +#include "VedAudiosettings.h" +#include +#include "VedAudioClipInfoImp.h" +#include "AudSong.h" +#include "AudClip.h" +#include "AudClipInfo.h" +#include "Vedqualitysettingsapi.h" +#include "ctrtranscoder.h" +#include "ctrtranscoderobserver.h" +#include "vedproctimeestimate.h" +#include "vedcodecchecker.h" + +#include + +const TInt KVedAudioTrackIndex = 1; + +// Print macro +#ifdef _DEBUG +#include +#define PRINT(x) RDebug::Print x +#else +#define PRINT(x) +#endif + + + +// Near-dummy observer class for temporary transcoder instance. In practice is only used to provide input framerate +// to the transcoder +class CTrObs : public CBase, public MTRTranscoderObserver + { +public: + /* Constructor & destructor */ + + inline CTrObs(TReal aFrameRate) : iInputFrameRate(aFrameRate) + { + }; + inline ~CTrObs() + { + }; + + // Dummy methods from MTRTranscoderObserver, just used to complete the observer class + inline void MtroInitializeComplete(TInt /*aError*/) + { + }; + inline void MtroFatalError(TInt /*aError*/) + { + }; + inline void MtroReturnCodedBuffer(CCMRMediaBuffer* /*aBuffer*/) + { + }; + // method to provide clip input framerate to transcoder + inline void MtroSetInputFrameRate(TReal& aRate) + { + aRate = iInputFrameRate; + }; + inline void MtroAsyncStopComplete() + { + }; + + inline void MtroSuspend() + { + }; + + inline void MtroResume() + { + }; + +private:// data + + // clip input framerate (fps) + TReal iInputFrameRate; + + }; + + +// -------- Local functions --------- + +// Map video format mimetype to editor's internal enumeration +static TVedVideoFormat MapVideoFormatTypes(const TText8* aVideoFormatType) + { + TPtrC8 mimeType(aVideoFormatType); + TBuf8<256> string; + string = _L8("video/3gpp"); + + if ( mimeType.MatchF( (const TDesC8& )string ) != KErrNotFound ) + { + return EVedVideoFormat3GPP; + } + else + { + string = _L8("video/mp4"); + if ( mimeType.MatchF( (const TDesC8& )string ) != KErrNotFound ) + { + return EVedVideoFormatMP4; + } + } + + return EVedVideoFormatUnrecognized; + } + +// Map video codec mimetype to editor's internal enumeration +static TVedVideoType MapVideoCodecTypes(const TText8* aVideoCodecType) + { + TPtrC8 mimeType(aVideoCodecType); + TBuf8<256> string; + string = _L8("video/H263*"); + + if ( mimeType.MatchF( (const TDesC8& )string ) != KErrNotFound ) + { + // H.263 + string = _L8("*level*"); + if ( mimeType.MatchF( (const TDesC8& )string ) != KErrNotFound ) + { + string = _L8("*level=10"); + if ( mimeType.MatchF( (const TDesC8& )string ) != KErrNotFound ) + { + return EVedVideoTypeH263Profile0Level10; + } + string = _L8("*level=45"); + if ( mimeType.MatchF( (const TDesC8& )string ) != KErrNotFound ) + { + return EVedVideoTypeH263Profile0Level45; + } + } + // no level specified => 10 + return EVedVideoTypeH263Profile0Level10; + } + else + { + string = _L8("video/mp4v-es*"); + if ( mimeType.MatchF( (const TDesC8& )string ) != KErrNotFound ) + { + return EVedVideoTypeMPEG4SimpleProfile; + } + + else + { + string = _L8("video/h264*"); + if ( mimeType.MatchF( (const TDesC8& )string ) != KErrNotFound ) + { + return EVedVideoTypeAVCBaselineProfile; + } + } + } + return EVedVideoTypeUnrecognized; + } + +// Map editor's internal enumeration to video codec mimetype +static void MapVideoCodecTypeToMime(TVedVideoType aType, TBufC8<255>& aMimeType) + { + switch ( aType ) + { + case EVedVideoTypeH263Profile0Level10: + { + aMimeType = KVedMimeTypeH263BaselineProfile; + } + break; + case EVedVideoTypeH263Profile0Level45: + { + aMimeType = KVedMimeTypeH263Level45; + } + break; + default: + { + //EVedVideoTypeMPEG4SimpleProfile + aMimeType = KVedMimeTypeMPEG4Visual; + } + } + } + + +// Map audio codec fourcc to editor's internal enumeration +static TAudType MapAudioCodecTypes(const TText8* aAudioCodecType) + { + TPtrC8 fourCCType(aAudioCodecType); + TBuf8<256> string; + string = _L8(" AMR"); + + if ( fourCCType.MatchF( (const TDesC8& )string ) != KErrNotFound ) + { + return EAudAMR; + } + else + { + string = _L8(" AAC"); + if ( fourCCType.MatchF( (const TDesC8& )string ) != KErrNotFound ) + { + return EAudAAC_MPEG4; + } + + } + return EAudTypeUnrecognized; + } + +// -------- Member functions --------- +EXPORT_C CVedMovie* CVedMovie::NewL(RFs *aFs) + { + PRINT(_L("CVedMovie::NewL")); + + CVedMovieImp* self = (CVedMovieImp*)NewLC(aFs); + CleanupStack::Pop(self); + return self; + } + + +EXPORT_C CVedMovie* CVedMovie::NewLC(RFs *aFs) + { + PRINT(_L("CVedMovie::NewLC")); + + CVedMovieImp* self = new (ELeave) CVedMovieImp(aFs); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + + +CVedMovieImp::CVedMovieImp(RFs *aFs) + : iFs(aFs), + iVideoClipArray(8), // Initial size of video clip array is 8 + iAudioClipInfoArray(8), // Initial size of audio clip array is 8 + iObserverArray(4), // Initial size of observer array is 4 + iStartTransitionEffect(EVedStartTransitionEffectNone), + iEndTransitionEffect(EVedEndTransitionEffectNone), + iQuality(EQualityAutomatic), + iNotifyObserver(ETrue), + iMovieProcessingObserver(0) + { + } + + +void CVedMovieImp::ConstructL() + { + iAudSong = CAudSong::NewL(iFs); + iAudSong->RegisterSongObserverL(this); + iAddOperation = CVedMovieAddClipOperation::NewL(this); + + iCodecChecker = CVedCodecChecker::NewL(); + iProcessor = CMovieProcessor::NewL(); + + PRINT((_L("CVedMovie::ConstructL() CVideoQualitySelector in use"))); + iQualitySelector = CVideoQualitySelector::NewL(); + + CalculatePropertiesL(); + } + + +CVedMovieImp::~CVedMovieImp() + { + DoReset(); + iObserverArray.Reset(); + + delete iAddOperation; + delete iCodecChecker; + delete iProcessor; + + delete iAudSong; + delete iAddedVideoClipFilename; + + delete iQualitySelector; + + REComSession::FinalClose(); + } + +CVedMovie::TVedMovieQuality CVedMovieImp::Quality() const + { + return iQuality; + } + +void CVedMovieImp::SetQuality(TVedMovieQuality aQuality) + { + __ASSERT_ALWAYS(aQuality >= EQualityAutomatic && aQuality < EQualityLast, + TVedPanic::Panic(TVedPanic::EMovieIllegalQuality)); + if (aQuality != iQuality) + { + iOutputParamsSet = EFalse; + TVedMovieQuality prevQuality = iQuality; + iQuality = aQuality; + TRAPD(err,CalculatePropertiesL());//should not leave with current implementation, but try to handle it anyway + if ( err == KErrNone ) + { + // successful + FireMovieQualityChanged(this); + } + else + { + // setting was not successful, use the previous value + iQuality = prevQuality; + TRAP(err,CalculatePropertiesL());// previous should always succee + } + + } + } + +TVedVideoFormat CVedMovieImp::Format() const + { + return iFormat; + } + +TVedVideoType CVedMovieImp::VideoType() const + { + return iVideoType; + } + +TSize CVedMovieImp::Resolution() const + { + return iResolution; + } + +TInt CVedMovieImp::MaximumFramerate() const + { + return iMaximumFramerate; + } + +TVedAudioType CVedMovieImp::AudioType() const + { + TAudType audioType = iAudSong->OutputFileProperties().iAudioType; + TVedAudioType vedAudioType = EVedAudioTypeUnrecognized; + + if (iAudSong->ClipCount(KAllTrackIndices) == 0) + { + vedAudioType = EVedAudioTypeNoAudio; + } + else if (audioType == EAudAMR) + { + vedAudioType = EVedAudioTypeAMR; + } + else if (audioType == EAudAAC_MPEG4 ) + { + vedAudioType = EVedAudioTypeAAC_LC; + } + else if (audioType == EAudNoAudio) + { + vedAudioType = EVedAudioTypeNoAudio; + } + + return vedAudioType; + } + +TInt CVedMovieImp::AudioSamplingRate() const + { + return iAudSong->OutputFileProperties().iSamplingRate; + } + +TVedAudioChannelMode CVedMovieImp::AudioChannelMode() const + { + TVedAudioChannelMode vedChannelMode = EVedAudioChannelModeUnrecognized; + if (iAudSong->OutputFileProperties().iChannelMode == EAudStereo) + { + vedChannelMode = EVedAudioChannelModeStereo; + } + else if (iAudSong->OutputFileProperties().iChannelMode == EAudSingleChannel) + { + vedChannelMode = EVedAudioChannelModeSingleChannel; + } + else if (iAudSong->OutputFileProperties().iChannelMode == EAudDualChannel) + { + vedChannelMode = EVedAudioChannelModeDualChannel; + } + return vedChannelMode; + } + + +TVedBitrateMode CVedMovieImp::AudioBitrateMode() const + { + TVedBitrateMode vedBitrateMode = EVedBitrateModeUnrecognized; + switch(iAudSong->OutputFileProperties().iBitrateMode) + { + case EAudConstant: + vedBitrateMode = EVedBitrateModeConstant; + break; + case EAudVariable: + vedBitrateMode = EVedBitrateModeVariable; + break; + default: + TVedPanic::Panic(TVedPanic::EInternal); + } + return vedBitrateMode; + } +TInt CVedMovieImp::AudioBitrate() const + { + return iAudSong->OutputFileProperties().iBitrate; + } + +TInt CVedMovieImp::VideoBitrate() const + { + // restricted bitrate: forces transcoding of video content to this bitrate + return iVideoRestrictedBitrate; + } + +TInt CVedMovieImp::VideoStandardBitrate() const + { + // the default bitrate to be used when encoding new content. This can be actually lower than the standard limit + // but it is not restricted bitrate that would trigger transcoding to happen + return iVideoStandardBitrate; + } + +TReal CVedMovieImp::VideoFrameRate() const + { + return iVideoFrameRate; + } + +// This must not be called for 3gp clips that should always have AMR audio +// returns ETrue if aAudioProperties contain settings found in input (can be modified by this method) +// and EFalse if client should decide what to do with them +TBool CVedMovieImp::MatchAudioPropertiesWithInput( TAudFileProperties& aAudioProperties ) + { + // If there are no audio clips + if (iAudSong->ClipCount(KAllTrackIndices) == 0) + { + return ETrue; + } + + // Go through the audio clips and select the best one + TAudFileProperties prop; + TAudFileProperties highestProp; + TBool highestPropFound = EFalse; + + for (TInt a = 0; a < iAudSong->ClipCount(KAllTrackIndices); a++) + { + CAudClip* clip = iAudSong->Clip(a, KAllTrackIndices); + prop = clip->Info()->Properties(); + + if ( ( prop.iChannelMode == aAudioProperties.iChannelMode ) && + ( prop.iSamplingRate == aAudioProperties.iSamplingRate ) ) + { + // there is a match => keep the properties + PRINT((_L("CVedMovie::MatchAudioPropertiesWithInput() found preferred set from input, sampling rate & channels %d & %d"), prop.iSamplingRate, prop.iChannelMode)); + return ETrue; + } + else + { + // need to stay within limits given by aAudioProperties (it has the highest preferred mode) + if ( ( prop.iAudioType == aAudioProperties.iAudioType ) && + ( prop.iSamplingRate <= aAudioProperties.iSamplingRate ) ) + { + // take the highest channelmode & sampling rate from input. + if ( !highestPropFound || + ( (prop.iSamplingRate > highestProp.iSamplingRate) || + ( (prop.iSamplingRate == highestProp.iSamplingRate) && (prop.iChannelMode > highestProp.iChannelMode) ) ) ) + { + PRINT((_L("CVedMovie::MatchAudioPropertiesWithInput() found new highest prop from input, sampling rate & channels %d & %d"), prop.iSamplingRate, prop.iChannelMode)); + highestProp.iAudioType = prop.iAudioType; + highestProp.iChannelMode = prop.iChannelMode; + highestProp.iSamplingRate = prop.iSamplingRate; + highestPropFound = ETrue; + } + } + } + } + + // if we come here, there was no exact match found. Use the best one, if found + if ( highestPropFound ) + { + // take the sampling rate and channel mode from inProp. Currently we support only 16k and 48k output, but this should be changed + // once we know what we need to support; but requires synchronization with audio editor engine + + if ( iAudSong->AreOutputPropertiesSupported(highestProp)) + { + PRINT((_L("CVedMovie::MatchAudioPropertiesWithInput() selected audio parameters, sampling rate & channels %d & %d"), highestProp.iSamplingRate, highestProp.iChannelMode)); + aAudioProperties.iChannelMode = highestProp.iChannelMode; + aAudioProperties.iSamplingRate = highestProp.iSamplingRate; + aAudioProperties.iBitrate = KAudBitRateDefault; //use default since we don't know the bitrate of the input. + return ETrue; + } + else + { + // We have some AAC in the input but it is not any of our supported sampling rates. + // The aAudioProperties may have 48k here but since we don't have such high input, better to use 16k in output + PRINT((_L("CVedMovie::MatchAudioPropertiesWithInput() no good match with input"))); + return EFalse; + } + } + else + { + // Not even a close match + PRINT((_L("CVedMovie::MatchAudioPropertiesWithInput() not even a close match with input"))); + return EFalse; + } + + } + + +// Set video codec mimetype member variable, and also max values that level defines (e.g. max framerate; actual values are taken from quality set) +void CVedMovieImp::SetVideoCodecMimeType(const TText8* aVideoCodecType) + { + TPtrC8 mimeType(aVideoCodecType); + + if ( mimeType.MatchF( KVedMimeTypeH263 ) != KErrNotFound ) + { + // H.263 baseline + iVideoCodecMimeType.Set(KVedMimeTypeH263BaselineProfile); + iMaximumFramerate = 15; + } + else if ( mimeType.MatchF( KVedMimeTypeH263BaselineProfile ) != KErrNotFound ) + { + // H.263 baseline + iVideoCodecMimeType.Set(KVedMimeTypeH263BaselineProfile); + iMaximumFramerate = 15; + } + else if (mimeType.MatchF( KVedMimeTypeH263Level45 ) != KErrNotFound ) + { + // H.263 level 45 + iVideoCodecMimeType.Set(KVedMimeTypeH263Level45); + iMaximumFramerate = 15; + } + else if (mimeType.MatchF( KVedMimeTypeMPEG4SimpleVisualProfileLevel2 ) != KErrNotFound ) + { + // MPEG-4 SP level 2 + iVideoCodecMimeType.Set(KVedMimeTypeMPEG4SimpleVisualProfileLevel2); + iMaximumFramerate = 15; + } + else if (mimeType.MatchF( KVedMimeTypeMPEG4SimpleVisualProfileLevel3 ) != KErrNotFound ) + { + // MPEG-4 SP level 3 + iVideoCodecMimeType.Set(KVedMimeTypeMPEG4SimpleVisualProfileLevel3); + iMaximumFramerate = 30; + } + else if (mimeType.MatchF( KVedMimeTypeMPEG4SimpleVisualProfileLevel4A ) != KErrNotFound ) + { + // MPEG-4 SP level 4a + iVideoCodecMimeType.Set(KVedMimeTypeMPEG4SimpleVisualProfileLevel4A); + iMaximumFramerate = 30; + } + else if (mimeType.MatchF( KVedMimeTypeMPEG4Visual ) != KErrNotFound ) + { + // MPEG-4 SP level 0 + iVideoCodecMimeType.Set(KVedMimeTypeMPEG4SimpleVisualProfile); + iMaximumFramerate = 15; + } + else if (mimeType.MatchF( KVedMimeTypeAVCBaselineProfileLevel1B ) != KErrNotFound ) + { + // AVC level 1b + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel1B); + iMaximumFramerate = 15; + } + else if (mimeType.MatchF( KVedMimeTypeAVCBaselineProfileLevel1_1 ) != KErrNotFound ) + { + // AVC level 1.1 + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel1_1); + iMaximumFramerate = 7.5; + } + else if (mimeType.MatchF( KVedMimeTypeAVCBaselineProfileLevel1_2 ) != KErrNotFound ) + { + // AVC level 1.2 + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel1_2); + iMaximumFramerate = 15; + } + //WVGA task + else if (mimeType.MatchF( KVedMimeTypeAVCBaselineProfileLevel1_3 ) != KErrNotFound ) + { + // AVC level 1.3 + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel1_3); + iMaximumFramerate = 15; + } + else if (mimeType.MatchF( KVedMimeTypeAVCBaselineProfileLevel2 ) != KErrNotFound ) + { + // AVC level 2 + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel2); + iMaximumFramerate = 15; + } + else if (mimeType.MatchF( KVedMimeTypeAVCBaselineProfileLevel2_1 ) != KErrNotFound ) + { + // AVC level 2.1 + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel2_1); + iMaximumFramerate = 15; + } + else if (mimeType.MatchF( KVedMimeTypeAVCBaselineProfileLevel2_2 ) != KErrNotFound ) + { + // AVC level 2.2 + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel2_2); + iMaximumFramerate = 15; + } + else if (mimeType.MatchF( KVedMimeTypeAVCBaselineProfileLevel3 ) != KErrNotFound ) + { + // AVC level 3 + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel3); + iMaximumFramerate = 15; + } + else if (mimeType.MatchF( KVedMimeTypeAVCBaselineProfileLevel3_1 ) != KErrNotFound ) + { + // AVC level 3.1 + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel3_1); + iMaximumFramerate = 15; + } + else + { + // AVC level 1 + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel1); + iMaximumFramerate = 15; + } + + } + + +// ----------------------------------------------------------------------------- +// CVedMovieImp::GetQCIFPropertiesL +// Get settings for QCIF or subQCIF resolution; H.263, H.264 or MPEG-4 +// This is a special case since it has also H.263 codec support. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CVedMovieImp::GetQCIFPropertiesL(SVideoQualitySet& aLocalQualitySet) + { + TInt foundQualitySetForLevelError = KErrNone; + + // QCIF and subQCIF are handled together, since they are covered by the same levels of the H.263, MPEG-4 and H.264. + // We have the preferred video codec in iVideoType (based on input clips) + + if ( iVideoType == EVedVideoTypeAVCBaselineProfile ) + { + // first check if we support H.264 output + // level 1B + PRINT((_L("CVedMovie::GetQCIFPropertiesL() check H.264 level 1B"))); + TRAP(foundQualitySetForLevelError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeAVCBaselineProfileLevel1B))); + + if ( foundQualitySetForLevelError == KErrNotSupported ) + { + // check H.264 level 1 instead + PRINT((_L("CVedMovie::GetQCIFPropertiesL() check H.264 level 1"))); + TRAP(foundQualitySetForLevelError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeAVCBaselineProfileLevel1))); + if ( foundQualitySetForLevelError == KErrNotSupported ) + { + // H.264 @ QCIF is not supported. Fall back to H.263 (=> input is transcoded to H.263) + PRINT((_L("CVedMovie::getQCIFPropertiesL() no set for MPEG-4 level 0, switch to H.263"))); + iVideoType = EVedVideoTypeH263Profile0Level45; // use level 45 since it is better than 10, and we don't have bitrate restrictions here + foundQualitySetForLevelError = GetQCIFPropertiesL(aLocalQualitySet); + // keep H.263; H.264 may not be supported at all + } + } + + if ( foundQualitySetForLevelError == KErrNone ) + { + SetVideoCodecMimeType(aLocalQualitySet.iVideoCodecMimeType); + } + } + else if ( iVideoType == EVedVideoTypeMPEG4SimpleProfile ) + { + // MPEG-4 @ QCIF is an exceptional case; should not happen for locally recorded clips, but support is kept here for compatibility + PRINT((_L("CVedMovie::GetQCIFPropertiesL() check MPEG-4 level 0"))); + TRAP(foundQualitySetForLevelError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeMPEG4SimpleVisualProfile))); + if ( foundQualitySetForLevelError == KErrNotSupported ) + { + // MPEG-4 QCIF is not listed in the quality set. Use it with H.263 settings, except the codec type + PRINT((_L("CVedMovie::GetQCIFPropertiesL() no set for MPEG-4 level 0, take settings from H.263"))); + iVideoType = EVedVideoTypeH263Profile0Level10;// level 10 is comparable to level 0 of MPEG-4; level 0b is not used + foundQualitySetForLevelError = GetQCIFPropertiesL(aLocalQualitySet); + // change back to MPEG-4 + iVideoType = EVedVideoTypeMPEG4SimpleProfile; + } + if ( foundQualitySetForLevelError == KErrNone ) + { + // set MPEG-4 MIME-type and other related settings; + // also if the quality set showed H.263; this way we can support mpeg-4 even if it is not any of the preferred ones, since we have supported it earlier too... + iVideoCodecMimeType.Set(KVedMimeTypeMPEG4SimpleVisualProfile); + iMaximumFramerate = 15; + } + } + else + { + // H.263 + if ( iVideoType == EVedVideoTypeH263Profile0Level45 ) + { + PRINT((_L("CVedMovie::GetQCIFPropertiesL() check H.263 level 45"))); + TRAP(foundQualitySetForLevelError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeH263Level45))); + } + if ( (iVideoType == EVedVideoTypeH263Profile0Level10) || (foundQualitySetForLevelError == KErrNotSupported) ) + { + PRINT((_L("CVedMovie::GetQCIFPropertiesL() check H.263 level 10"))); + TRAP(foundQualitySetForLevelError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeH263))); + } + + if ( foundQualitySetForLevelError == KErrNone ) + { + SetVideoCodecMimeType(aLocalQualitySet.iVideoCodecMimeType); + } + } + // assume subQCIF can use other QCIF settings except resolution + + + return foundQualitySetForLevelError; + } + + +// ----------------------------------------------------------------------------- +// CVedMovieImp::GetCIFQVGAPropertiesL +// Get settings for CIF or QVGA resolution; H.264 or MPEG-4 +// Some encoders may not support both, hence we may need to change the resolution here +// and that's why this is treated as a special case. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CVedMovieImp::GetCIFQVGAPropertiesL(TSize aSize, TReal aFrameRate, SVideoQualitySet& aLocalQualitySet) + { + TInt foundQualitySetForLevelError = KErrNone; + + // CIF and QVGA are handled together, since they are covered by the same levels of the MPEG-4 and H.264; + // framerate brings a difference though. + // We have the preferred video codec in iVideoType (based on input clips), and framerate in aFrameRate + // so let's check the level first, and then additionally check if the resolution is supported. + + if ( iVideoType == EVedVideoTypeAVCBaselineProfile ) + { + // first check if we support H.264 output + // try level 1.2; higher levels not supported yet, and hence aFrameRate has no impact; + // level 1.1 is not seen relevant since it supports only 7.5 fps + PRINT((_L("CVedMovie::GetCIFQVGAPropertiesL() check H.264 level 1.2"))); + TRAP(foundQualitySetForLevelError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeAVCBaselineProfileLevel1_2))); + if ( foundQualitySetForLevelError == KErrNotSupported ) + { + // H.264 level 1.2 is not supported; switch to MPEG-4 + iVideoType = EVedVideoTypeMPEG4SimpleProfile; + } + } + + if ( iVideoType == EVedVideoTypeMPEG4SimpleProfile ) + { + // MPEG-4 was dominant in the input, OR H.264 is not supported in quality set. + // The order is like this since MPEG-4 is generally more supported than H.264. + // Hence this CANNOT handle the case where MPEG-4 CIF/QVGA is not in the quality set but H.264 is, but in that case it falls back to H.263 QCIF in the host method + if ( aFrameRate > 15.0 ) + { + // check level 3 + PRINT((_L("CVedMovie::GetCIFQVGAPropertiesL() check MPEG-4 level 3"))); + TRAP(foundQualitySetForLevelError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeMPEG4SimpleVisualProfileLevel3))); + } + if ( (aFrameRate <= 15.0) || (foundQualitySetForLevelError == KErrNotSupported) ) + { + // try level 2 + PRINT((_L("CVedMovie::GetCIFQVGAPropertiesL() check MPEG-4 level 2"))); + TRAP(foundQualitySetForLevelError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeMPEG4SimpleVisualProfileLevel2))); + } + } + + if ( foundQualitySetForLevelError == KErrNotSupported ) + { + // these resolutions are not supported! The default one will be taken into use in CalculatePropertiesL + PRINT((_L("CVedMovie::GetCIFQVGAPropertiesL() no support for CIF/QVGA found in quality set"))); + return foundQualitySetForLevelError; + } + + + + SVideoQualitySet tmpSet; + TRAPD(resolutionSupported, iQualitySelector->GetVideoQualitySetL( tmpSet, aSize)); + if ( resolutionSupported == KErrNotSupported ) + { + // the preferred resolution is not supported => must use the other one + // the level was supported already, so no need to check support for the other one + if ( aSize == KVedResolutionCIF ) + { + PRINT((_L("CVedMovie::GetCIFQVGAPropertiesL() CIF support not available, must use QVGA instead"))); + iResolution = KVedResolutionQVGA; + } + else + { + PRINT((_L("CVedMovie::GetCIFQVGAPropertiesL() QVGA support not available, must use CIF instead"))); + iResolution = KVedResolutionCIF; + } + } + else + { + PRINT((_L("CVedMovie::GetCIFQVGAPropertiesL() resolution support ok"))); + iResolution = aSize; + } + + // at this point we must have found a suitable set + SetVideoCodecMimeType(aLocalQualitySet.iVideoCodecMimeType); + return foundQualitySetForLevelError; + } + + +// ----------------------------------------------------------------------------- +// CVedMovieImp::GetVGAPropertiesL +// Get settings for VGA resolution. If not supported, get High settings instead +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CVedMovieImp::GetVGAPropertiesL(SVideoQualitySet& aLocalQualitySet) + { + TInt foundQualitySetForResolutionError = KErrNone; + + if ( iVideoType == EVedVideoTypeAVCBaselineProfile ) + { + PRINT((_L("CVedMovie::GetWVGAPropertiesL() check H.264 level 3.0"))); + TRAP(foundQualitySetForResolutionError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeAVCBaselineProfileLevel3))); + if (foundQualitySetForResolutionError == KErrNotSupported ) + { + PRINT((_L("CVedMovie::GetVGAPropertiesL() H.264 level 3.0 not supported"))); + // H.264 level 3.0 is not supported; switch to MPEG-4 + iVideoType = EVedVideoTypeMPEG4SimpleProfile; + } + else + { + PRINT((_L("CVedMovie::GetVGAPropertiesL() H.264 level 3.0 supported"))); + iResolution = KVedResolutionVGA; + SetVideoCodecMimeType(aLocalQualitySet.iVideoCodecMimeType); + } + } + + if ( iVideoType == EVedVideoTypeMPEG4SimpleProfile ) + { + // VGA; check MPEG-4 level 4a + // Settings may not exist => trap the leave + TRAP(foundQualitySetForResolutionError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeMPEG4SimpleVisualProfileLevel4A))); + if ( foundQualitySetForResolutionError == KErrNotSupported ) + { + PRINT((_L("CVedMovie::GetVGAPropertiesL() VGA not supported as output, try highest supported"))); + // No VGA, try the highest instead + foundQualitySetForResolutionError = GetHighPropertiesL(aLocalQualitySet); + } + else + { + PRINT((_L("CVedMovie::GetVGAPropertiesL() VGA with MPEG-4 level 4a selected as output"))); + iResolution = KVedResolutionVGA; + SetVideoCodecMimeType(aLocalQualitySet.iVideoCodecMimeType); + } + } + + return foundQualitySetForResolutionError; + } + +// ----------------------------------------------------------------------------- +// CVedMovieImp::GetVGA16By9PropertiesL +// Get settings for VGA 16:9 resolution. If not supported, get High settings instead +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CVedMovieImp::GetVGA16By9PropertiesL(SVideoQualitySet& aLocalQualitySet) + { + TInt foundQualitySetForResolutionError = KErrNone; + + if ( iVideoType != EVedVideoTypeMPEG4SimpleProfile ) + { + // NOTE: max supported H.264/AVC level currently (1.2) allows only CIF 15 fps, no VGA. + PRINT((_L("CVedMovie::GetVGA16By9PropertiesL() VGA & H.264 == NOT SUPPORTED"))); + TVedPanic::Panic(TVedPanic::EInternal); + } + + // VGA; check MPEG-4 level 4a + // Settings may not exist => trap the leave + TRAP(foundQualitySetForResolutionError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeMPEG4SimpleVisualProfileLevel4A))); + if ( foundQualitySetForResolutionError == KErrNotSupported ) + { + PRINT((_L("CVedMovie::GetVGAPropertiesL() VGA 16:9 not supported as output, try highest supported"))); + // No VGA, try the highest instead + foundQualitySetForResolutionError = GetHighPropertiesL(aLocalQualitySet); + } + else + { + PRINT((_L("CVedMovie::GetVGAPropertiesL() VGA 16:9 with MPEG-4 level 4a selected as output"))); + iResolution = KVedResolutionVGA16By9; + SetVideoCodecMimeType(aLocalQualitySet.iVideoCodecMimeType); + } + return foundQualitySetForResolutionError; + } + +//WVGA task +// ----------------------------------------------------------------------------- +// CVedMovieImp::GetWVGAPropertiesL +// ----------------------------------------------------------------------------- +// +TInt CVedMovieImp::GetWVGAPropertiesL(SVideoQualitySet& aLocalQualitySet) + { + TInt foundQualitySetForResolutionError = KErrNone;; + + if ( iVideoType == EVedVideoTypeAVCBaselineProfile ) + { + PRINT((_L("CVedMovie::GetWVGAPropertiesL() check H.264 level 3.1"))); + TRAP(foundQualitySetForResolutionError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeAVCBaselineProfileLevel3))); + if (foundQualitySetForResolutionError == KErrNotSupported ) + { + PRINT((_L("CVedMovie::GetWVGAPropertiesL() H.264 level 3.0 not supported"))); + // H.264 level 3.0 is not supported; switch to MPEG-4 + iVideoType = EVedVideoTypeMPEG4SimpleProfile; + } + else + { + PRINT((_L("CVedMovie::GetWVGAPropertiesL() H.264 level 3.0 supported"))); + iResolution = KVedResolutionWVGA; + SetVideoCodecMimeType(aLocalQualitySet.iVideoCodecMimeType); + } + } + + if ( iVideoType == EVedVideoTypeMPEG4SimpleProfile ) + { + // Settings may not exist => trap the leave + TRAP(foundQualitySetForResolutionError,iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, TPtrC8(KVedMimeTypeMPEG4SimpleVisualProfileLevel4A))); + if ( foundQualitySetForResolutionError == KErrNotSupported ) + { + PRINT((_L("CVedMovie::GetWVGAPropertiesL() WVGA not supported as output, try highest supported"))); + // No WVGA, try the highest instead + foundQualitySetForResolutionError = GetHighPropertiesL(aLocalQualitySet); + } + else + { + PRINT((_L("CVedMovie::GetWVGAPropertiesL() WVGA with MPEG-4 level 4a selected as output"))); + iResolution = KVedResolutionWVGA; + SetVideoCodecMimeType(aLocalQualitySet.iVideoCodecMimeType); + } + + } + return foundQualitySetForResolutionError; + + } + +// ----------------------------------------------------------------------------- +// CVedMovieImp::GetHighPropertiesL +// Get settings for High quality and apply relevant parts to member variables; +// the rest are applied in common part +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CVedMovieImp::GetHighPropertiesL(SVideoQualitySet& aLocalQualitySet) + { + TInt foundQualitySetForResolutionError = KErrNone; + + PRINT((_L("CVedMovie::SetHighPropertiesL() use the highest supported"))); + TRAP(foundQualitySetForResolutionError, iQualitySelector->GetVideoQualitySetL( aLocalQualitySet, CVideoQualitySelector::EVideoQualityHigh)); + if ( foundQualitySetForResolutionError == KErrNone ) + { + iResolution.iWidth = aLocalQualitySet.iVideoWidth; + iResolution.iHeight = aLocalQualitySet.iVideoHeight; + iVideoType = MapVideoCodecTypes(aLocalQualitySet.iVideoCodecMimeType); + SetVideoCodecMimeType(aLocalQualitySet.iVideoCodecMimeType); + } + else + { + // handled in the end of CalculatePropertiesL, but should not be possible to reach this since High should always exist + } + + return foundQualitySetForResolutionError; + } + + +// ----------------------------------------------------------------------------- +// CVedMovieImp::ApplyAutomaticPropertiesL +// Apply the settings based on properties of input clips +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVedMovieImp::ApplyAutomaticPropertiesL(TAudFileProperties &aAudioProperties) + { + // Automatic quality selection + + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() automatic quality selected"))); + TTimeIntervalMicroSeconds durationOfMP4MPEG4(0); + TTimeIntervalMicroSeconds durationOfMP4AVC(0); + + TTimeIntervalMicroSeconds durationOf3gppH263(0); + TTimeIntervalMicroSeconds durationOf3gppMPEG4(0); + TTimeIntervalMicroSeconds durationOf3gppAVC(0); + + TTimeIntervalMicroSeconds durationOfVGA(0); + TTimeIntervalMicroSeconds durationOfVGA16By9(0); + TTimeIntervalMicroSeconds durationOfQVGA(0); + TTimeIntervalMicroSeconds durationOfCIF(0); + TTimeIntervalMicroSeconds durationOfQCIF(0); + TTimeIntervalMicroSeconds durationOfSubQCIF(0); + TReal frameRateOfQVGA(0); + TReal frameRateOfCIF(0); + TReal framerate(0); + TBool audioOnlyMP4 = EFalse; + + //WVGA task + TTimeIntervalMicroSeconds durationOfWVGA(0); + TReal frameRateOfWVGA(0); + + iVideoType = EVedVideoTypeH263Profile0Level10; + + for (TInt i = 0; i < VideoClipCount(); i++) + { + CVedVideoClipInfo* currentInfo = VideoClip(i)->Info(); + + if (currentInfo->Class() == EVedVideoClipClassFile) + { + // Add up the durations of different resolution video + if (currentInfo->Resolution() == KVedResolutionSubQCIF) + { + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() subQCIF input"))); + durationOfSubQCIF= durationOfSubQCIF.Int64() + VideoClip(i)->EditedDuration().Int64(); + } + else if (currentInfo->Resolution() == KVedResolutionQCIF) + { + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() QCIF input"))); + durationOfQCIF= durationOfQCIF.Int64() + VideoClip(i)->EditedDuration().Int64(); + } + else if (currentInfo->Resolution() == KVedResolutionCIF) + { + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() CIF input"))); + durationOfCIF= durationOfCIF.Int64() + VideoClip(i)->EditedDuration().Int64(); + framerate = (1000*currentInfo->VideoFrameCount())/(currentInfo->Duration().Int64()/1000); + if ( framerate > frameRateOfCIF ) + { + frameRateOfCIF = framerate; + } + } + else if (currentInfo->Resolution() == KVedResolutionQVGA) + { + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() QVGA input"))); + durationOfQVGA= durationOfQVGA.Int64() + VideoClip(i)->EditedDuration().Int64(); + framerate = (1000*currentInfo->VideoFrameCount())/(currentInfo->Duration().Int64()/1000); + if ( framerate > frameRateOfQVGA ) + { + frameRateOfQVGA = framerate; + } + } + else if (currentInfo->Resolution() == KVedResolutionVGA16By9) + { + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() VGA 16:9 input"))); + durationOfVGA16By9 = durationOfVGA16By9.Int64() + VideoClip(i)->EditedDuration().Int64(); + } + + else if (currentInfo->Resolution() == KVedResolutionVGA) + { + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() VGA input"))); + durationOfVGA= durationOfVGA.Int64() + VideoClip(i)->EditedDuration().Int64(); + } + //WVGA task + else if (currentInfo->Resolution() == KVedResolutionWVGA) + { + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() WVGA input"))); + durationOfWVGA= durationOfWVGA.Int64() + VideoClip(i)->EditedDuration().Int64(); + } + + + if (currentInfo->Format() == EVedVideoFormat3GPP) + { + if ( currentInfo->VideoType() == EVedVideoTypeMPEG4SimpleProfile ) + { + // 3gpp file with MPEG-4 video + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() 3gpp with MPEG-4 input"))); + durationOf3gppMPEG4 = durationOf3gppMPEG4.Int64() + VideoClip(i)->EditedDuration().Int64(); + } + else if ( currentInfo->VideoType() == EVedVideoTypeAVCBaselineProfile ) + { + // 3gpp file with AVC video + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() 3gpp with AVC input"))); + durationOf3gppAVC = durationOf3gppAVC.Int64() + VideoClip(i)->EditedDuration().Int64(); + // NOTE: Level 1B is assumed always for QCIF AVC in automatic input case. + } + else + { + // 3gpp file with H.263 video + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() 3gpp with H.263 input"))); + durationOf3gppH263 = durationOf3gppH263.Int64() + VideoClip(i)->EditedDuration().Int64(); + if (currentInfo->VideoType() == EVedVideoTypeH263Profile0Level45) + { + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() 3gpp with H.263 L45 input"))); + iVideoType = EVedVideoTypeH263Profile0Level45; + } + } + } + + else if (currentInfo->Format() == EVedVideoFormatMP4) + { + + if ( currentInfo->VideoType() == EVedVideoTypeMPEG4SimpleProfile ) + { + // MP4 file with MPEG-4 video + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() MP4 with MPEG-4 input"))); + durationOfMP4MPEG4 = durationOfMP4MPEG4.Int64() + VideoClip(i)->EditedDuration().Int64(); + } + + else if ( currentInfo->VideoType() == EVedVideoTypeAVCBaselineProfile ) + { + // MP4 file with AVC video + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() MP4 with AVC input"))); + durationOfMP4AVC = durationOfMP4AVC.Int64() + VideoClip(i)->EditedDuration().Int64(); + // NOTE: What about levels ? + } + + else + { + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() MP4 with other input, not supported"))); + TVedPanic::Panic(TVedPanic::EInternal); + } + + } + else + { + // Unknown format + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() not 3gpp nor MP4 , not supported"))); + TVedPanic::Panic(TVedPanic::EInternal); + } + } + } // end of for loop, all input has been checked now + + + + // + // Decide the output format + // + + // First check if we had any video + if ( (durationOfMP4MPEG4.Int64() == 0) && (durationOfMP4AVC.Int64() == 0) && + (durationOf3gppH263.Int64() == 0) && (durationOf3gppMPEG4.Int64() == 0) && (durationOf3gppAVC.Int64() == 0) + ) + { + // no video, check audio + for ( TInt i = 0; i < iAudSong->ClipCount(KVedAudioTrackIndex); i++) + { + if ( iAudSong->Clip(i, KVedAudioTrackIndex)->Info()->Properties().iAudioType == EAudAMR ) + { + // 3gpp + durationOf3gppH263 = durationOf3gppH263.Int64() + iAudSong->Clip(i, KVedAudioTrackIndex)->EditedDuration().Int64(); + } + else + { + // mp4; mark audio-only as Mpeg4 video at this point + durationOfMP4MPEG4 = durationOfMP4MPEG4.Int64() + iAudSong->Clip(i, KVedAudioTrackIndex)->EditedDuration().Int64(); + audioOnlyMP4 = ETrue; + } + } + } + + // Then decide the file format + if ( ( durationOfMP4MPEG4.Int64() + durationOfMP4AVC.Int64() > 0 ) && + ( ( durationOfMP4MPEG4.Int64() + durationOfMP4AVC.Int64() ) >= + ( durationOf3gppH263.Int64() + durationOf3gppMPEG4.Int64() + durationOf3gppAVC.Int64() ) ) ) + { + // majority of input is MP4 + iFormat = EVedVideoFormatMP4; + if ( audioOnlyMP4 ) + { + // no video, just audio, use highest quality; this branch is only used to skip the else-branches + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() audio only with MP4"))); + // iVideoType is set in GetHighPropertiesL based on high quality level + } + else if ( durationOfMP4MPEG4 > durationOfMP4AVC ) + { + // MP4, video is MPEG-4 + iVideoType = EVedVideoTypeMPEG4SimpleProfile; + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is MP4 with MPEG-4 video"))); + } + else + { + // MP4, video is AVC + iVideoType = EVedVideoTypeAVCBaselineProfile; + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is MP4 with AVC video"))); + } + } + else + { + // majority of input is 3gpp, or no video. Keep 3gpp as in previous versions + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is 3gpp or no video"))); + iFormat = EVedVideoFormat3GPP; + + if ((durationOf3gppMPEG4 > 0) && + (durationOf3gppMPEG4 >= durationOf3gppAVC) && + (durationOf3gppMPEG4 >= durationOf3gppH263)) + { + iVideoType = EVedVideoTypeMPEG4SimpleProfile; + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is 3gpp with MPEG-4 video"))); + } + + else if ((durationOf3gppAVC > 0) && + (durationOf3gppAVC >= durationOf3gppH263)) + { + iVideoType = EVedVideoTypeAVCBaselineProfile; + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is 3gpp with AVC video"))); + } + + else + { + // H.263 + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is 3gpp with H.263 video"))); + if ( iVideoType != EVedVideoTypeH263Profile0Level45 ) + { + //use level 10 as used in previous versions + iVideoType = EVedVideoTypeH263Profile0Level10; + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is 3gpp with H.263 L10 video"))); + } + + } + } + + + + + // Then decide the resolution + + + + // cannot use the iQualitySet since it overrides the video settings. Use this mainly for checking audio settings + SVideoQualitySet localQualitySet; + TInt foundQualitySetForResolutionError = KErrNone; + + if ( audioOnlyMP4 ) + { + // get video parameters for audio-only MP4 clip; audio-only 3gpp is handled as QCIF + foundQualitySetForResolutionError = GetHighPropertiesL(localQualitySet); + } + //WVGA task + else if ((durationOfWVGA > 0) && + (durationOfWVGA >= durationOfVGA) && + (durationOfWVGA >= durationOfVGA16By9) && + (durationOfWVGA >= durationOfQVGA) && + (durationOfWVGA >= durationOfCIF) && + (durationOfWVGA >= durationOfQCIF) && + (durationOfWVGA >= durationOfSubQCIF)) + { + // VGA + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is WVGA"))); + iResolution = KVedResolutionWVGA; + foundQualitySetForResolutionError = GetWVGAPropertiesL(localQualitySet); + } + else if ((durationOfVGA > 0) && + (durationOfVGA >= durationOfVGA16By9) && + (durationOfVGA >= durationOfQVGA) && + (durationOfVGA >= durationOfCIF) && + (durationOfVGA >= durationOfQCIF) && + (durationOfVGA >= durationOfSubQCIF)) + { + // VGA + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is VGA"))); + iResolution = KVedResolutionVGA; + foundQualitySetForResolutionError = GetVGAPropertiesL(localQualitySet); + } + + else if ((durationOfVGA16By9 > 0) && + (durationOfVGA16By9 >= durationOfCIF) && + (durationOfVGA16By9 >= durationOfQVGA) && + (durationOfVGA16By9 >= durationOfQCIF) && + (durationOfVGA16By9 >= durationOfSubQCIF)) + { + // VGA 16:9 + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is VGA 16:9"))); + iResolution = KVedResolutionVGA16By9; + foundQualitySetForResolutionError = GetVGA16By9PropertiesL(localQualitySet); + } + + else if ((durationOfCIF > 0) && + (durationOfCIF >= durationOfQVGA) && + (durationOfCIF >= durationOfQCIF) && + (durationOfCIF >= durationOfSubQCIF)) + { + // CIF, but may be translated to QVGA if CIF not supported as output + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is CIF"))); + iResolution = KVedResolutionCIF; + foundQualitySetForResolutionError = GetCIFQVGAPropertiesL(KVedResolutionCIF, frameRateOfCIF, localQualitySet); + // audio parameters set in the end + } + else if ((durationOfQVGA > 0) && + (durationOfQVGA >= durationOfQCIF) && + (durationOfQVGA >= durationOfSubQCIF)) + { + // QVGA, but may be translated to CIF if QVGA not supported as output + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is QVGA"))); + iResolution = KVedResolutionQVGA; + foundQualitySetForResolutionError = GetCIFQVGAPropertiesL(KVedResolutionQVGA, frameRateOfQVGA, localQualitySet); + // audio parameters set in the end + } + else if ((durationOfSubQCIF > 0) && + (durationOfSubQCIF > durationOfQCIF)) // keep the > and not >= since QCIF is better than subQCIF + { + // subQCIF is not that important but is kept here anyway + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is subQCIF"))); + iResolution = KVedResolutionSubQCIF; + foundQualitySetForResolutionError = GetQCIFPropertiesL(localQualitySet); + // audio parameters set in the end + } + else + { + // QCIF + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() majority of input is QCIF"))); + iResolution = KVedResolutionQCIF; + foundQualitySetForResolutionError = GetQCIFPropertiesL(localQualitySet); + // audio parameters set in the end + } + + if ( foundQualitySetForResolutionError == KErrNone ) + { + // iVideoType and MIME-type were set earlier. + iVideoStandardBitrate = localQualitySet.iVideoBitRate; + iVideoFrameRate = localQualitySet.iVideoFrameRate; + iRandomAccessRate = localQualitySet.iRandomAccessRate; + // audio parameters set in the end + } + + + // Then handle cases where we didn't found suitable output format based on input resolution + // (i.e. we can't generate output that matches with majority of input) + if ( foundQualitySetForResolutionError == KErrNotSupported ) + { + + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() no suitable quality set found yet..."))); + // did not get preferred set from qualityselector; use highest one; may be overruled in MatchAudioPropertiesWithInput + if (iFormat == EVedVideoFormatMP4 ) + { + // MP4 => AAC + // High quality should be always present + + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() try taking the high quality"))); + TRAPD(err,iQualitySelector->GetVideoQualitySetL( localQualitySet, CVideoQualitySelector::EVideoQualityHigh)); + if ( err ) + { + // should not happen if the variation is done properly + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() problem in getting high quality set, ERROR"))); + User::Leave( err ); + } + + aAudioProperties.iAudioType = MapAudioCodecTypes(localQualitySet.iAudioFourCCType); + aAudioProperties.iSamplingRate = localQualitySet.iAudioSamplingRate; + if ( localQualitySet.iAudioChannels == 1 ) + { + aAudioProperties.iChannelMode = EAudSingleChannel; + } + else + { + aAudioProperties.iChannelMode = EAudStereo; + } + aAudioProperties.iBitrate = localQualitySet.iAudioBitRate; + // take also video settings from the new set + iResolution.iWidth = localQualitySet.iVideoWidth; + iResolution.iHeight = localQualitySet.iVideoHeight; + // MIME-type and bitrate + SetVideoCodecMimeType(localQualitySet.iVideoCodecMimeType); + iVideoStandardBitrate = localQualitySet.iVideoBitRate; + } + else + { + PRINT((_L("CVedMovie::ApplyAutomaticPropertiesL() use 3gpp"))); + // 3gp => use AMR + aAudioProperties.iAudioType = EAudAMR; + aAudioProperties.iSamplingRate = KVedAudioSamplingRate8k; + aAudioProperties.iChannelMode = EAudSingleChannel; + aAudioProperties.iBitrate = KAudBitRateDefault; //use default. + // set also video settings for 3gpp + iResolution = KVedResolutionQCIF; + // MIME-type and bitrate + iVideoCodecMimeType.Set(KVedMimeTypeH263); + iVideoStandardBitrate = KVedBitRateH263Level10; + } + + } + else + { + // preferred settings were got from quality set API without any error; take the audio settings too + + aAudioProperties.iAudioType = MapAudioCodecTypes(localQualitySet.iAudioFourCCType); + aAudioProperties.iSamplingRate = localQualitySet.iAudioSamplingRate; + if ( localQualitySet.iAudioChannels == 1 ) + { + aAudioProperties.iChannelMode = EAudSingleChannel; + } + else + { + aAudioProperties.iChannelMode = EAudStereo; + } + aAudioProperties.iBitrate = localQualitySet.iAudioBitRate; + } + + + + if ( aAudioProperties.iAudioType != EAudAMR ) + { + // still check that we don't do unnecessary audio transcoding. AMR output is not changed to anything else + if ( !MatchAudioPropertiesWithInput( aAudioProperties ) ) + { + // there was no input clip that matched the properties + + if ( foundQualitySetForResolutionError == KErrNotSupported ) + { + // the properties were taken from highest quality set after not finding a suitable set; better to ensure we have 16k + aAudioProperties.iSamplingRate = KVedAudioSamplingRate16k; + aAudioProperties.iChannelMode = EAudSingleChannel; + aAudioProperties.iBitrate = KAudBitRateDefault; //use default. + } + // else the properties were taken from a suitable set; convert audio to match them + + } + } + + } + +// ----------------------------------------------------------------------------- +// CVedMovieImp::ApplyRequestedPropertiesL +// Apply the settings the client requested +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVedMovieImp::ApplyRequestedPropertiesL(TAudFileProperties &aAudioProperties) + { + TBool legacyMode = EFalse; + + if (iQuality == EQualityMMSInteroperability) + { + // MMS interoperability settings + PRINT((_L("CVedMovie::ApplyRequestedPropertiesL() MMS quality selected"))); + // MMS interoperability should be always there => no leave + iQualitySelector->GetVideoQualitySetL( iQualitySet, CVideoQualitySelector::EVideoQualityMMS); + // map the set to member variables later + + } + + else if (iQuality == EQualityResolutionQCIF) + { + // this is a legacy branch, used only with older editor UI + PRINT((_L("CVedMovie::ApplyRequestedPropertiesL() QCIF quality selected; check level 45 vs level 10"))); + legacyMode = ETrue; + + iResolution = KVedResolutionQCIF; + + // Start with MMS and upgrade based on input if needed + iQualitySelector->GetVideoQualitySetL( iQualitySet, CVideoQualitySelector::EVideoQualityMMS); + iFormat = MapVideoFormatTypes(iQualitySet.iVideoFileMimeType); + iVideoType = MapVideoCodecTypes(iQualitySet.iVideoCodecMimeType); + + aAudioProperties.iAudioType = MapAudioCodecTypes(iQualitySet.iAudioFourCCType); + aAudioProperties.iSamplingRate = iQualitySet.iAudioSamplingRate; + if ( iQualitySet.iAudioChannels == 1 ) + { + aAudioProperties.iChannelMode = EAudSingleChannel; + } + else + { + aAudioProperties.iChannelMode = EAudStereo; + } + aAudioProperties.iBitrate = iQualitySet.iAudioBitRate; + + + for (TInt i = 0; i < VideoClipCount(); i++) + { + CVedVideoClipInfo* currentInfo = VideoClip(i)->Info(); + + // Go through all files and check if any are H.263 Profile0 Level45 + if (currentInfo->Class() == EVedVideoClipClassFile) + { + if (currentInfo->VideoType() == EVedVideoTypeH263Profile0Level45) + { + iVideoType = EVedVideoTypeH263Profile0Level45; + } + } + } + + + if ( iVideoType == EVedVideoTypeH263Profile0Level45 ) + { + iVideoCodecMimeType.Set(KVedMimeTypeH263Level45); + iVideoStandardBitrate = KVedBitRateH263Level45; + } + else + { + iVideoCodecMimeType.Set(KVedMimeTypeH263); + iVideoStandardBitrate = KVedBitRateH263Level10; + } + } + + else if (iQuality == EQualityResolutionCIF) + { + // this is a legacy branch, used only with older editor UI + PRINT((_L("CVedMovie::ApplyRequestedPropertiesL() CIF quality selected"))); + legacyMode = ETrue; + iFormat = EVedVideoFormatMP4; + iVideoType = EVedVideoTypeMPEG4SimpleProfile; + iResolution = KVedResolutionCIF; + iVideoCodecMimeType.Set(KVedMimeTypeMPEG4SimpleVisualProfileLevel2); + iVideoStandardBitrate = KVedBitRateMPEG4Level2; + // use 16 kHz mono AAC, as used to be the selection with CIF in older editor versions + aAudioProperties.iAudioType = EAudAAC_MPEG4; + aAudioProperties.iSamplingRate = KVedAudioSamplingRate16k; + aAudioProperties.iChannelMode = EAudSingleChannel; + aAudioProperties.iBitrate = KAudBitRateDefault; //use default. + } + else if (iQuality == EQualityResolutionMedium) + { + PRINT((_L("CVedMovie::ApplyRequestedPropertiesL() medium quality selected"))); + // Medium quality should be always there => no leave + iQualitySelector->GetVideoQualitySetL( iQualitySet, CVideoQualitySelector::EVideoQualityNormal); + // map the set to member variables later + + } + else if (iQuality == EQualityResolutionHigh) + { + PRINT((_L("CVedMovie::ApplyRequestedPropertiesL() high quality selected"))); + // High quality should be always there => no leave + iQualitySelector->GetVideoQualitySetL( iQualitySet, CVideoQualitySelector::EVideoQualityHigh); + // map the set to member variables later + + } + + if ( !legacyMode ) // legacyMode is forced CIF or QCIF; their parameters were set already, this is for others + { + // set common video settings from the obtained iQualitySet. In automatic case they were taken from input + iFormat = MapVideoFormatTypes(iQualitySet.iVideoFileMimeType); + iVideoType = MapVideoCodecTypes(iQualitySet.iVideoCodecMimeType); + iResolution.iWidth = iQualitySet.iVideoWidth; + iResolution.iHeight = iQualitySet.iVideoHeight; + iVideoFrameRate = iQualitySet.iVideoFrameRate; + iVideoStandardBitrate = iQualitySet.iVideoBitRate; // still not restricted => not necessary to transcode + SetVideoCodecMimeType(iQualitySet.iVideoCodecMimeType); + iRandomAccessRate = iQualitySet.iRandomAccessRate; + + aAudioProperties.iAudioType = MapAudioCodecTypes(iQualitySet.iAudioFourCCType); + aAudioProperties.iSamplingRate = iQualitySet.iAudioSamplingRate; + if ( iQualitySet.iAudioChannels == 1 ) + { + aAudioProperties.iChannelMode = EAudSingleChannel; + } + else + { + aAudioProperties.iChannelMode = EAudStereo; + } + aAudioProperties.iBitrate = iQualitySet.iAudioBitRate; + } + } + + +// ----------------------------------------------------------------------------- +// CVedMovieImp::CalculatePropertiesL +// Determine & apply the output properties for movie +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CVedMovieImp::CalculatePropertiesL() + { + PRINT((_L("CVedMovie::CalculatePropertiesL() in"))); + + if (iOutputParamsSet) + return; + + if ( (VideoClipCount() == 0) && (AudioClipCount() == 0) ) + { + PRINT((_L("CVedMovie::CalculatePropertiesL() no clips in movie, out"))); + return; + } + + + // set some default values. These will be updated if needed, in the two functions called below + // default video framerate is 15 + iVideoFrameRate = iMaximumFramerate = 15.0; + // default random access rate is 1/5 fps + iRandomAccessRate = 0.2; + + TAudFileProperties audioProperties; + + if ( iQuality == EQualityAutomatic ) + { + // Automatic quality selection based on input + ApplyAutomaticPropertiesL(audioProperties); + } + else + { + // forced quality + ApplyRequestedPropertiesL(audioProperties); + } + + + + // Common finalization + + PRINT((_L("CVedMovie::CalculatePropertiesL() fileformat: %d"), iFormat)); + PRINT((_L("CVedMovie::CalculatePropertiesL() video codec, resolution, bitrate, framerate, random access rate: %d, (%d,%d), %d, %f, %f"), iVideoType, iResolution.iWidth, iResolution.iHeight, iVideoStandardBitrate, iVideoFrameRate, iRandomAccessRate)); + PRINT((_L("CVedMovie::CalculatePropertiesL() audio codec, samplingrate, channels: %d, %d, %d"), audioProperties.iAudioType, audioProperties.iSamplingRate, audioProperties.iChannelMode)); + + // Set the audio output properties here to the values specified above + if ( !iAudSong->SetOutputFileFormat(audioProperties.iAudioType, audioProperties.iSamplingRate,audioProperties.iChannelMode, audioProperties.iBitrate ) ) + { + PRINT((_L("CVedMovie::CalculatePropertiesL() iAudSong->SetOutputFileFormat failed, try again with default settings"))); + // something was wrong with the settings. Use default ones that should always work: + if ( audioProperties.iAudioType == EAudAMR ) + { + audioProperties.iSamplingRate = KVedAudioSamplingRate8k; + audioProperties.iChannelMode = EAudSingleChannel; + } + else + { + audioProperties.iAudioType = EAudAAC_MPEG4; + audioProperties.iSamplingRate = KVedAudioSamplingRate16k; + audioProperties.iChannelMode = EAudSingleChannel; + } + // try again; bitrate is default + iAudSong->SetOutputFileFormat(audioProperties.iAudioType, audioProperties.iSamplingRate, audioProperties.iChannelMode); + } + + } + + +void CVedMovieImp::SetAudioFadingL() + { + // Apply fading only if there are no specific dynamic level marks inserted. + // I.e. this is used only if audio volume is set by SetxxVolumeGainL or not set at all + if ( !iApplyDynamicLevelMark ) + { + + iNotifyObserver = EFalse; + for (TInt index = 0; index < VideoClipCount(); index++) + { + TBool fadeIn = EFalse; + TBool fadeOut = EFalse; + if ( index == 0 ) + { + // first clip, allow fade in always + fadeIn = ETrue; + } + else if (iVideoClipArray[index-1]->iMiddleTransitionEffect != EVedMiddleTransitionEffectNone) + { + // there is a transition effect before this clip, allow fade in + fadeIn = ETrue; + } + else + { + // no transition, no audio fading either + fadeIn = EFalse; + } + + if ( index == VideoClipCount()-1 ) + { + // last clip, allow fade out always + fadeOut = ETrue; + } + else if (iVideoClipArray[index]->iMiddleTransitionEffect != EVedMiddleTransitionEffectNone) + { + // there is a transition effect after this clip, allow fade out + fadeOut = ETrue; + } + else + { + // no transition, no audio fading either + fadeOut = EFalse; + } + + CVedVideoClip* clip = iVideoClipArray[index]; + + if (clip->EditedHasAudio() && !clip->IsMuted() && (fadeIn || fadeOut)) + { + + TTimeIntervalMicroSeconds clipLength = + TTimeIntervalMicroSeconds( clip->CutOutTime().Int64() - clip->CutInTime().Int64() ); + + // Do fading only if clip length is over 1 second + // Otherwise the original markers remain untouched + if ( clipLength > TTimeIntervalMicroSeconds(1000000) ) + { + // get normal level + TInt normalLevel = 0; + + // get normal level + + // NOTE: This assumes that the client has set a constant + // gain value for the whole clip, i.e. two markers, + // one at the beginning and other at the end + // iApplyDynamicLevelMark now controls that removing others is safe + + normalLevel = clip->GetVolumeGain(); + + // remove all existing markers + while (clip->DynamicLevelMarkCount()) + { + clip->RemoveDynamicLevelMark(0); + } + + // add movie-level volume gain + normalLevel += iVolumeGainForAllVideoClips; + + // use normal - 50dB as lower level; step in values is 0.5db + TInt lowLevel = normalLevel - 100; + if ( lowLevel < -127 ) + { + lowLevel = -127; + } + + // 0s: low + TVedDynamicLevelMark mark1(clip->CutInTime(), lowLevel); + + // 0.5s: normal + TTimeIntervalMicroSeconds time = + TTimeIntervalMicroSeconds(clip->CutInTime().Int64() + + TInt64(500000) ); + + TVedDynamicLevelMark mark2(time, normalLevel); + + // clip length - 0.5s: normal + time = TTimeIntervalMicroSeconds(clip->CutOutTime().Int64() - + TInt64(500000) ); + + TVedDynamicLevelMark mark3(time, normalLevel); + + // clip length: low + TVedDynamicLevelMark mark4(clip->CutOutTime(), lowLevel); + + if ( fadeIn ) + { + clip->InsertDynamicLevelMarkL(mark1); + clip->InsertDynamicLevelMarkL(mark2); + } + if ( fadeOut ) + { + clip->InsertDynamicLevelMarkL(mark3); + clip->InsertDynamicLevelMarkL(mark4); + } + } + } + } + + for (TInt index = 0; index < AudioClipCount(); index++) + { + CAudClip* clip = iAudSong->Clip(index, KVedAudioTrackIndex); + + if (!clip->Muting()) + { + + TTimeIntervalMicroSeconds clipLength = + TTimeIntervalMicroSeconds( clip->CutOutTime().Int64() - clip->CutInTime().Int64() ); + + // Do fading only if clip length is over 1 second + // Otherwise the original markers remain untouched + if ( clipLength > TTimeIntervalMicroSeconds(1000000) ) + { + // get normal level + TInt normalLevel = 0; + + // get normal level + + // NOTE: This assumes that the client has set a constant + // gain value for the whole clip, i.e. two markers, + // one at the beginning and other at the end + // iApplyDynamicLevelMark now controls that removing others is safe + + normalLevel = clip->GetVolumeGain(); + + // remove all existing markers + while (clip->DynamicLevelMarkCount()) + { + clip->RemoveDynamicLevelMark(0); + } + // add movie-level volume gain + normalLevel += iVolumeGainForAllAudioClips; + + // use normal - 50dB as lower level; step in values is 0.5db + TInt lowLevel = normalLevel - 100; + if ( lowLevel < -127 ) + { + lowLevel = -127; + } + + // 0s: low + TAudDynamicLevelMark mark1(clip->CutInTime(), lowLevel); + + // 0.5s: normal + TTimeIntervalMicroSeconds time = + TTimeIntervalMicroSeconds(clip->CutInTime().Int64() + + TInt64(500000) ); + + TAudDynamicLevelMark mark2(time, normalLevel); + + // clip length - 0.5s: normal + time = TTimeIntervalMicroSeconds(clip->CutOutTime().Int64() - + TInt64(500000) ); + + TAudDynamicLevelMark mark3(time, normalLevel); + + // clip length: low + TAudDynamicLevelMark mark4(clip->CutOutTime(), lowLevel); + + clip->InsertDynamicLevelMarkL(mark1); + clip->InsertDynamicLevelMarkL(mark2); + clip->InsertDynamicLevelMarkL(mark3); + clip->InsertDynamicLevelMarkL(mark4); + } + } + } + + iNotifyObserver = ETrue; + } + } + +void CVedMovieImp::SetOutputParametersL(TVedOutputParameters& aOutputParams) +{ + PRINT((_L("CVedMovie::SetOutputParametersL(), aOutputParams: video %d, (%dx%d), %d bps, %ffps"), aOutputParams.iVideoType, aOutputParams.iVideoResolution.iWidth, aOutputParams.iVideoResolution.iHeight, aOutputParams.iVideoBitrate, aOutputParams.iVideoFrameRate)); + PRINT((_L("CVedMovie::SetOutputParametersL(), aOutputParams: audio %d, %d bps, s/m: %d, %d Hz"), aOutputParams.iAudioType, aOutputParams.iAudioBitrate, aOutputParams.iAudioChannelMode, aOutputParams.iAudioSamplingRate)); + PRINT((_L("CVedMovie::SetOutputParametersL(), aOutputParams: video segmentation: %d GOBs, %d bytes/segment"), aOutputParams.iSyncIntervalInPicture, aOutputParams.iSegmentSizeInBytes)); + + if (aOutputParams.iVideoType != EVedVideoTypeUnrecognized && + aOutputParams.iVideoType != EVedVideoTypeNoVideo) + { + iVideoType = aOutputParams.iVideoType; + } + + if ( (aOutputParams.iVideoResolution != TSize(0, 0)) && + (aOutputParams.iVideoResolution != KVedResolutionSubQCIF) && + (aOutputParams.iVideoResolution != KVedResolutionQCIF) && + (aOutputParams.iVideoResolution != KVedResolutionCIF) && + (aOutputParams.iVideoResolution != KVedResolutionQVGA) && + (aOutputParams.iVideoResolution != KVedResolutionVGA16By9) && + (aOutputParams.iVideoResolution != KVedResolutionVGA) && + (aOutputParams.iVideoResolution != KVedResolutionWVGA) ) + { + User::Leave(KErrNotSupported); + } + +#ifndef VIDEOEDITORENGINE_AVC_EDITING + if ( iVideoType == EVedVideoTypeAVCBaselineProfile ) + User::Leave(KErrNotSupported); +#endif + + // Allow AVC & MPEG-4 QVGA/CIF + if ( ( aOutputParams.iVideoResolution == KVedResolutionCIF ) || + ( aOutputParams.iVideoResolution == KVedResolutionQVGA ) ) + { + if ( iVideoType == EVedVideoTypeH263Profile0Level10 || + iVideoType == EVedVideoTypeH263Profile0Level45 ) + User::Leave(KErrNotSupported); + + } + // Allow MPEG VGA + if ( aOutputParams.iVideoResolution == KVedResolutionVGA ) + { + if ( iVideoType != EVedVideoTypeMPEG4SimpleProfile ) + User::Leave(KErrNotSupported); + } + + if (aOutputParams.iVideoResolution != TSize(0,0)) + iResolution = aOutputParams.iVideoResolution; + + switch (iVideoType) + { + case EVedVideoTypeH263Profile0Level10: + + // check bitrate + if ( aOutputParams.iVideoBitrate > KVedBitRateH263Level10 ) + User::Leave(KErrNotSupported); + iVideoCodecMimeType.Set(KVedMimeTypeH263); + break; + + case EVedVideoTypeH263Profile0Level45: + + // check bitrate + if ( aOutputParams.iVideoBitrate > KVedBitRateH263Level45 ) + User::Leave(KErrNotSupported); + iVideoCodecMimeType.Set(KVedMimeTypeH263Level45); + break; + + case EVedVideoTypeMPEG4SimpleProfile: + + // check bitrate + if ( iResolution == KVedResolutionCIF || iResolution == KVedResolutionQVGA ) + { + if ( aOutputParams.iVideoBitrate > KVedBitRateMPEG4Level2 ) + User::Leave(KErrNotSupported); + iVideoCodecMimeType.Set(KVedMimeTypeMPEG4SimpleVisualProfileLevel2); + } + + else if ( iResolution == KVedResolutionVGA || iResolution == KVedResolutionVGA16By9 ) + { + if ( aOutputParams.iVideoBitrate > KVedBitRateMPEG4Level4A ) + User::Leave(KErrNotSupported); + iVideoCodecMimeType.Set(KVedMimeTypeMPEG4SimpleVisualProfileLevel4A); + } + + else + { + if ( aOutputParams.iVideoBitrate > KVedBitRateMPEG4Level0 ) + User::Leave(KErrNotSupported); + iVideoCodecMimeType.Set(KVedMimeTypeMPEG4SimpleVisualProfile); + } + break; + + case EVedVideoTypeAVCBaselineProfile: + + // check bitrate + //WVGA task + if ( iResolution == KVedResolutionWVGA ) + { + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel3_1); + } + + else if ( iResolution == KVedResolutionCIF || iResolution == KVedResolutionQVGA ) + { + if ( aOutputParams.iVideoBitrate > KVedBitRateAVCLevel1_2 ) + User::Leave(KErrNotSupported); + if ( aOutputParams.iVideoBitrate <= KVedBitRateAVCLevel1_1 ) + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel1_1); + else + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel1_2); + } + else + { + if ( aOutputParams.iVideoBitrate > KVedBitRateAVCLevel1b ) + User::Leave(KErrNotSupported); + if ( aOutputParams.iVideoBitrate <= KVedBitRateAVCLevel1 ) + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel1); + else + iVideoCodecMimeType.Set(KVedMimeTypeAVCBaselineProfileLevel1B); + } + break; + + default: + User::Leave(KErrArgument); + + } + + // check if the selected codec/resolution is a supported format + TBool supported = iCodecChecker->IsSupportedOutputFormatL(iVideoCodecMimeType, iResolution); + if ( !supported ) + { + PRINT(_L("CVedMovie::SetOutputParametersL(), format not supported")); + User::Leave(KErrNotSupported); + } + + // can be zero => not used + iVideoStandardBitrate = iVideoRestrictedBitrate = aOutputParams.iVideoBitrate; + + // check frame rate + if (aOutputParams.iVideoFrameRate > KVedMaxVideoFrameRate) + User::Leave(KErrNotSupported); + + // default random access rate is 1/5 fps + iRandomAccessRate = 0.2; + + // can be zero => not used + iVideoFrameRate = aOutputParams.iVideoFrameRate; + + if (aOutputParams.iAudioType == EVedAudioTypeNoAudio) + { + // use default audio for this video + switch (iVideoType) + { + case EVedVideoTypeH263Profile0Level10: + case EVedVideoTypeH263Profile0Level45: + aOutputParams.iAudioType = EVedAudioTypeAMR; + break; + + case EVedVideoTypeMPEG4SimpleProfile: + case EVedVideoTypeAVCBaselineProfile: + default: + aOutputParams.iAudioType = EVedAudioTypeAAC_LC; + break; + } + + } + + if (aOutputParams.iAudioType != EVedAudioTypeAMR && + aOutputParams.iAudioType != EVedAudioTypeAAC_LC ) + User::Leave(KErrNotSupported); + + if ( aOutputParams.iAudioChannelMode != EVedAudioChannelModeStereo && + aOutputParams.iAudioChannelMode != EVedAudioChannelModeDualChannel && + aOutputParams.iAudioChannelMode != EVedAudioChannelModeSingleChannel ) + User::Leave(KErrArgument); + + if ( aOutputParams.iAudioType == EVedAudioTypeAMR ) + { + if ( aOutputParams.iAudioBitrate != 0 && + aOutputParams.iAudioBitrate != KVedAMRBitrate4_75k && + aOutputParams.iAudioBitrate != KVedAMRBitrate5_15k && + aOutputParams.iAudioBitrate != KVedAMRBitrate5_90k && + aOutputParams.iAudioBitrate != KVedAMRBitrate6_70k && + aOutputParams.iAudioBitrate != KVedAMRBitrate7_40k && + aOutputParams.iAudioBitrate != KVedAMRBitrate7_95k && + aOutputParams.iAudioBitrate != KVedAMRBitrate10_2k && + aOutputParams.iAudioBitrate != KVedAMRBitrate12_2k ) + { + User::Leave(KErrNotSupported); + } + + if ( aOutputParams.iAudioSamplingRate != 0 && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate8k ) + User::Leave(KErrNotSupported); + + if ( aOutputParams.iAudioChannelMode != EVedAudioChannelModeSingleChannel ) + User::Leave(KErrNotSupported); + + } + + else if (aOutputParams.iAudioType == EVedAudioTypeAAC_LC) + { + if ( aOutputParams.iAudioSamplingRate != 0 && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate8k && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate11_025k && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate12k && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate16k && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate22_050k && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate24k && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate32k && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate44_1k && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate48k && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate64k && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate88_2k && + aOutputParams.iAudioSamplingRate != KVedAudioSamplingRate96k ) + { + User::Leave(KErrNotSupported); + } + + TInt numChannels = 1; + if ( aOutputParams.iAudioChannelMode == EVedAudioChannelModeStereo || + aOutputParams.iAudioChannelMode == EVedAudioChannelModeDualChannel ) + numChannels = 2; + + TInt samplingRate = (aOutputParams.iAudioSamplingRate != 0) ? aOutputParams.iAudioSamplingRate : KVedAudioSamplingRate16k; + + TInt minBitrate = 1 * numChannels * samplingRate; + TInt maxBitrate = 6 * numChannels * samplingRate; + + if ( aOutputParams.iAudioBitrate > 0 && + (aOutputParams.iAudioBitrate < minBitrate || aOutputParams.iAudioBitrate > maxBitrate) ) + User::Leave(KErrNotSupported); + + } + + if ( iVideoType == EVedVideoTypeH263Profile0Level10 || + iVideoType == EVedVideoTypeH263Profile0Level45 ) + { + // For H.263 + iSyncIntervalInPicture = aOutputParams.iSyncIntervalInPicture; + + // Segment size not supported for H.263 + if ( aOutputParams.iSegmentSizeInBytes != 0 ) + User::Leave(KErrNotSupported); + } + else + { + // For H.264 and MPEG-4 + iSyncIntervalInPicture = aOutputParams.iSegmentSizeInBytes; + + // Sync interval not supported for H.264 and MPEG-4 + if ( aOutputParams.iSyncIntervalInPicture != 0 ) + User::Leave(KErrNotSupported); + } + + TAudFileProperties audioProperties; + + if (aOutputParams.iAudioType == EVedAudioTypeAMR) + audioProperties.iAudioType = EAudAMR; + + else if (aOutputParams.iAudioType == EVedAudioTypeAAC_LC) + audioProperties.iAudioType = EAudAAC_MPEG4; + + if (aOutputParams.iAudioBitrate > 0) + audioProperties.iBitrate = aOutputParams.iAudioBitrate; + + if (aOutputParams.iAudioSamplingRate > 0) + audioProperties.iSamplingRate = aOutputParams.iAudioSamplingRate; + + audioProperties.iChannelMode = EAudSingleChannel; + + if (aOutputParams.iAudioChannelMode == EVedAudioChannelModeStereo) + audioProperties.iChannelMode = EAudStereo; + + else if (aOutputParams.iAudioChannelMode == EAudDualChannel) + audioProperties.iChannelMode = EAudDualChannel; + + // Set the audio output properties here to the values specified above + if ( iAudSong->SetOutputFileFormat(audioProperties.iAudioType, audioProperties.iSamplingRate,audioProperties.iChannelMode, audioProperties.iBitrate) ) + { + iOutputParamsSet = ETrue; + FireMovieOutputParametersChanged(this); + } + else + { + // parameters didn't work + User::Leave( KErrArgument ); + } +} + + +TInt CVedMovieImp::CheckVideoClipInsertable(CVedVideoClip *aClip) const + { + /* Check format and video and audio types of a file-based clip. */ + if ( !aClip ) + { + return KErrGeneral; + } + + if (aClip->iInfo->Class() == EVedVideoClipClassFile) + { + if ( (aClip->iInfo->Format() != EVedVideoFormat3GPP) && + (aClip->iInfo->Format() != EVedVideoFormatMP4) + ) + { + return KErrNotSupported; + } + + if ( (aClip->iInfo->VideoType() != EVedVideoTypeH263Profile0Level10) && + (aClip->iInfo->VideoType() != EVedVideoTypeH263Profile0Level45) && + (aClip->iInfo->VideoType() != EVedVideoTypeMPEG4SimpleProfile) && + (aClip->iInfo->VideoType() != EVedVideoTypeAVCBaselineProfile) + ) + { + return KErrNotSupported; + } + + if ( (aClip->iInfo->AudioType() != EVedAudioTypeNoAudio) && + (aClip->iInfo->AudioType() != EVedAudioTypeAMR) && + (aClip->iInfo->AudioType() != EVedAudioTypeAMRWB) && + (aClip->iInfo->AudioType() != EVedAudioTypeAAC_LC) ) + { + return KErrNotSupported; + } + + if ( (aClip->iInfo->AudioType() != EVedAudioTypeNoAudio) && aClip->iInfo->AudioChannelMode() == EVedAudioChannelModeUnrecognized ) + { + return KErrNotSupported; + } + } + + if (aClip->Info()->Class() == EVedVideoClipClassFile) + { + TInt error = KErrNone; + TBool supported = EFalse; + + // check if clip format / resolution is supported + TRAP( error, supported = iCodecChecker->IsSupportedInputClipL(aClip) ); + + if ( error != KErrNone ) + { + return error; + } + + if ( !supported ) + { + PRINT(_L("CVedMovie::CheckVideoClipInsertable(), clip not supported")); + return KErrNotSupported; + } + } + + return KErrNone; + } + + +TInt CVedMovieImp::GetSizeEstimateL() const + { + PRINT(_L("CVedMovieImp::GetSizeEstimateL")); + + if ((VideoClipCount() == 0) && (AudioClipCount() == 0)) + { + return 0; + } + + if ( iProcessor ) + { + return iProcessor->GetMovieSizeEstimateL(this); + } + else + { + return 0; + } + } + +void CVedMovieImp::GetDurationEstimateL(TInt aTargetSize, + TTimeIntervalMicroSeconds aStartTime, + TTimeIntervalMicroSeconds& aEndTime) + { + if ((VideoClipCount() == 0) && (AudioClipCount() == 0)) + { + User::Leave( KErrNotReady ); + } + + if ( iProcessor ) + { + User::LeaveIfError( iProcessor->GetMovieSizeEstimateForMMSL(this, + aTargetSize, + aStartTime, + aEndTime) ); + } + else + { + User::Leave( KErrNotReady ); + } + } + + +TBool CVedMovieImp::IsMovieMMSCompatible() const + { + return ( ( iFormat == EVedVideoFormat3GPP ) && + ( iVideoType == EVedVideoTypeH263Profile0Level10 ) && + ( AudioType() == EVedAudioTypeAMR ) ); + } + + +void CVedMovieImp::InsertVideoClipL(const TDesC& aFileName, TInt aIndex) + { + PRINT(_L("CVedMovieImp::InsertVideoClipL")); + + __ASSERT_ALWAYS(iAddOperation->iVideoClip == 0, + TVedPanic::Panic(TVedPanic::EMovieAddOperationAlreadyRunning)); + iAddedVideoClipIndex = aIndex; + + if (iAddedVideoClipFilename) + { + delete iAddedVideoClipFilename; + iAddedVideoClipFilename = 0; + } + + iAddedVideoClipFilename = HBufC::NewL(aFileName.Size()); + *iAddedVideoClipFilename = aFileName; + iAddedVideoClipFileHandle = NULL; + + // add audio clip + TTimeIntervalMicroSeconds startTime(0); + + if (aIndex > 0) + { + startTime = VideoClipEndTime(aIndex - 1); + } + iAudSong->AddClipL(aFileName, startTime); + } + +void CVedMovieImp::InsertVideoClipL(RFile* aFileHandle, TInt aIndex) + { + PRINT(_L("CVedMovieImp::InsertVideoClipL")); + + __ASSERT_ALWAYS(iAddOperation->iVideoClip == 0, + TVedPanic::Panic(TVedPanic::EMovieAddOperationAlreadyRunning)); + iAddedVideoClipIndex = aIndex; + + if (iAddedVideoClipFilename) + { + delete iAddedVideoClipFilename; + iAddedVideoClipFilename = 0; + } + + iAddedVideoClipFileHandle = aFileHandle; + + // add audio clip + TTimeIntervalMicroSeconds startTime(0); + + if (aIndex > 0) + { + startTime = VideoClipEndTime(aIndex - 1); + } + iAudSong->AddClipL(aFileHandle, startTime); + } + + + +void CVedMovieImp::InsertVideoClipL(CVedVideoClipGenerator& aGenerator, + TBool aIsOwnedByVideoClip, TInt aIndex) + { + PRINT(_L("CVedMovieImp::InsertVideoClipL")); + + __ASSERT_ALWAYS(iAddOperation->iVideoClip == 0, + TVedPanic::Panic(TVedPanic::EMovieAddOperationAlreadyRunning)); + + iAddOperation->iVideoClip = CVedVideoClip::NewL(this, aGenerator, + aIndex, *iAddOperation, aIsOwnedByVideoClip); + iAddOperation->iIsVideoGeneratorOwnedByVideoClip = aIsOwnedByVideoClip; + } + + +void CVedMovieImp::RemoveVideoClip(TInt aIndex) + { + PRINT(_L("CVedMovieImp::RemoveVideoClip")); + + if ( (aIndex > VideoClipCount()) || (aIndex < 0) ) + { + return; + } + + CVedVideoClip* clip = iVideoClipArray[aIndex]; + TBool hasAudio = clip->EditedHasAudio(); + if (hasAudio) + { + iAudSong->RemoveClip(clip->iAudClip->IndexOnTrack(), 0); + } + + iVideoClipArray.Remove(aIndex); + delete clip; + + if (aIndex < VideoClipCount()) + { + clip = iVideoClipArray[aIndex]; + clip->iIndex = aIndex; + RecalculateVideoClipTimings(clip); + } + else if (VideoClipCount() > 0) + { + clip = iVideoClipArray[aIndex - 1]; + RecalculateVideoClipTimings(clip); + } + + TRAPD(err,CalculatePropertiesL());// ignore error? + if (err != KErrNone) { } + + FireVideoClipRemoved(this, aIndex); + } + + +void CVedMovieImp::RecalculateVideoClipTimings(CVedVideoClip* aVideoClip) + { + TInt index = aVideoClip->iIndex; + + TInt64 startTime; + if (index == 0) + { + startTime = 0; + } + else + { + startTime = iVideoClipArray[index - 1]->EndTime().Int64(); + } + + for (; index < VideoClipCount(); index++) + { + CVedVideoClip* clip = iVideoClipArray[index]; + clip->iIndex = index; + clip->iStartTime = startTime; + clip->UpdateAudioClip(); + startTime = clip->EndTime().Int64(); + } + iAudSong->SetDuration(Duration()); + } + + +void CVedMovieImp::SetStartTransitionEffect(TVedStartTransitionEffect aEffect) + { + __ASSERT_ALWAYS(VideoClipCount() > 0, TVedPanic::Panic(TVedPanic::EMovieEmpty)); + __ASSERT_ALWAYS((aEffect >= EVedStartTransitionEffectNone) + && (aEffect < EVedStartTransitionEffectLast), + TVedPanic::Panic(TVedPanic::EMovieIllegalStartTransitionEffect)); + + if (aEffect != iStartTransitionEffect) + { + iStartTransitionEffect = aEffect; + FireStartTransitionEffectChanged(this); + } + } + + +void CVedMovieImp::SetMiddleTransitionEffect(TVedMiddleTransitionEffect aEffect, + TInt aIndex) + { + __ASSERT_ALWAYS((aEffect >= EVedMiddleTransitionEffectNone) + && (aEffect < EVedMiddleTransitionEffectLast), + TVedPanic::Panic(TVedPanic::EMovieIllegalMiddleTransitionEffect)); + + if (aIndex == (iVideoClipArray.Count() - 1)) + { + aIndex++; // make aIndex out of range to cause panic + } + + if (aEffect != iVideoClipArray[aIndex]->iMiddleTransitionEffect) + { + iVideoClipArray[aIndex]->iMiddleTransitionEffect = aEffect; + FireMiddleTransitionEffectChanged(this, aIndex); + } + } + + +void CVedMovieImp::SetEndTransitionEffect(TVedEndTransitionEffect aEffect) + { + __ASSERT_ALWAYS(VideoClipCount() > 0, TVedPanic::Panic(TVedPanic::EMovieEmpty)); + __ASSERT_ALWAYS((aEffect >= EVedEndTransitionEffectNone) + && (aEffect < EVedEndTransitionEffectLast), + TVedPanic::Panic(TVedPanic::EMovieIllegalEndTransitionEffect)); + + if (aEffect != iEndTransitionEffect) + { + iEndTransitionEffect = aEffect; + FireEndTransitionEffectChanged(this); + } + } + + +void CVedMovieImp::AddAudioClipL(const TDesC& aFileName, + TTimeIntervalMicroSeconds aStartTime, + TTimeIntervalMicroSeconds aCutInTime, + TTimeIntervalMicroSeconds aCutOutTime) + { + __ASSERT_ALWAYS(iAddOperation->iVideoClip == 0, + TVedPanic::Panic(TVedPanic::EMovieAddOperationAlreadyRunning)); + + iAudSong->AddClipL(aFileName, aStartTime, KVedAudioTrackIndex, aCutInTime, aCutOutTime); + } + +void CVedMovieImp::AddAudioClipL(RFile* aFileHandle, + TTimeIntervalMicroSeconds aStartTime, + TTimeIntervalMicroSeconds aCutInTime, + TTimeIntervalMicroSeconds aCutOutTime) + { + __ASSERT_ALWAYS(iAddOperation->iVideoClip == 0, + TVedPanic::Panic(TVedPanic::EMovieAddOperationAlreadyRunning)); + + iAudSong->AddClipL(aFileHandle, aStartTime, KVedAudioTrackIndex, aCutInTime, aCutOutTime); + } + + +void CVedMovieImp::RemoveAudioClip(TInt aIndex) + { + iAudSong->RemoveClip(aIndex, KVedAudioTrackIndex); + } + +void CVedMovieImp::Reset() + { + DoReset(); + + FireMovieReseted(this); + } + + +void CVedMovieImp::DoReset() + { + iVideoClipArray.ResetAndDestroy(); + iAudioClipInfoArray.ResetAndDestroy(); + + iStartTransitionEffect = EVedStartTransitionEffectNone; + iEndTransitionEffect = EVedEndTransitionEffectNone; + + if (iAudSong != 0) + { + iAudSong->Reset(EFalse); + } + } + + +void CVedMovieImp::RegisterMovieObserverL(MVedMovieObserver* aObserver) + { + PRINT(_L("CVedMovieImp::RegisterMovieObserverL")); + + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + if (iObserverArray[i] == aObserver) + { + TVedPanic::Panic(TVedPanic::EMovieObserverAlreadyRegistered); + } + } + + User::LeaveIfError(iObserverArray.Append(aObserver)); + } + + +void CVedMovieImp::UnregisterMovieObserver(MVedMovieObserver* aObserver) + { + PRINT(_L("CVedMovieImp::UnregisterMovieObserver")); + + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + if (iObserverArray[i] == aObserver) + { + iObserverArray.Remove(i); + return; + } + } + } + +TBool CVedMovieImp::MovieObserverIsRegistered(MVedMovieObserver* aObserver) + { + PRINT(_L("CVedMovieImp::MovieObserverIsRegistered")); + + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + if (iObserverArray[i] == aObserver) + { + return ETrue; + } + } + + return EFalse; + } + +CVedVideoClipInfo* CVedMovieImp::VideoClipInfo(TInt aIndex) const + { + return iVideoClipArray[aIndex]->Info(); + } + +TBool CVedMovieImp::VideoClipEditedHasAudio(TInt aIndex) const + { + return iVideoClipArray[aIndex]->EditedHasAudio(); + } + +void CVedMovieImp::VideoClipSetIndex(TInt aOldIndex, TInt aNewIndex) + { + iVideoClipArray[aOldIndex]->SetIndex(aNewIndex); + } + +TInt CVedMovieImp::VideoClipSpeed(TInt aIndex) const + { + return iVideoClipArray[aIndex]->Speed(); + } + +void CVedMovieImp::VideoClipSetSpeed(TInt aIndex, TInt aSpeed) + { + iVideoClipArray[aIndex]->SetSpeed(aSpeed); + } + +TVedColorEffect CVedMovieImp::VideoClipColorEffect(TInt aIndex) const + { + return iVideoClipArray[aIndex]->ColorEffect(); + } + +void CVedMovieImp::VideoClipSetColorEffect(TInt aIndex, TVedColorEffect aColorEffect) + { + iVideoClipArray[aIndex]->SetColorEffect(aColorEffect); + } + +TBool CVedMovieImp::VideoClipIsMuteable(TInt aIndex) const + { + return iVideoClipArray[aIndex]->IsMuteable(); + } + +TBool CVedMovieImp::VideoClipIsMuted(TInt aIndex) const + { + return iVideoClipArray[aIndex]->IsMuted(); + } + +void CVedMovieImp::VideoClipSetMuted(TInt aIndex, TBool aMuted) + { + iVideoClipArray[aIndex]->SetMuted(aMuted); + } + +TBool CVedMovieImp::VideoClipNormalizing(TInt aIndex) const + { + return iVideoClipArray[aIndex]->Normalizing(); + } + +void CVedMovieImp::VideoClipSetNormalizing(TInt aIndex, TBool aNormalizing) + { + iVideoClipArray[aIndex]->SetNormalizing(aNormalizing); + } + +void CVedMovieImp::VideoClipInsertDynamicLevelMarkL(TInt aIndex, TVedDynamicLevelMark aMark) + { + __ASSERT_ALWAYS(aIndex >= 0, + TVedPanic::Panic(TVedPanic::EVideoClipIllegalIndex)); + + iApplyDynamicLevelMark = ETrue; + iVideoClipArray[aIndex]->InsertDynamicLevelMarkL(aMark); + } + +void CVedMovieImp::VideoClipRemoveDynamicLevelMark(TInt aClipIndex, TInt aMarkIndex) + { + __ASSERT_ALWAYS(aClipIndex >= 0, + TVedPanic::Panic(TVedPanic::EVideoClipIllegalIndex)); + + iVideoClipArray[aClipIndex]->RemoveDynamicLevelMark(aMarkIndex); + } + +TInt CVedMovieImp::VideoClipDynamicLevelMarkCount(TInt aIndex) const + { + __ASSERT_ALWAYS(aIndex >= 0, + TVedPanic::Panic(TVedPanic::EVideoClipIllegalIndex)); + + return iVideoClipArray[aIndex]->DynamicLevelMarkCount(); + } + +TVedDynamicLevelMark CVedMovieImp::VideoClipDynamicLevelMark(TInt aClipIndex, TInt aMarkIndex) + { + __ASSERT_ALWAYS(aClipIndex >= 0, + TVedPanic::Panic(TVedPanic::EVideoClipIllegalIndex)); + + return iVideoClipArray[aClipIndex]->DynamicLevelMark(aMarkIndex); + } + +TTimeIntervalMicroSeconds CVedMovieImp::VideoClipCutInTime(TInt aIndex) const + { + return iVideoClipArray[aIndex]->CutInTime(); + } + +void CVedMovieImp::VideoClipSetCutInTime(TInt aIndex, TTimeIntervalMicroSeconds aCutInTime) + { + iVideoClipArray[aIndex]->SetCutInTime(aCutInTime); + // basically we should call CalculatePropertiesL after this one, but since it is called in StartMovie, we can probably skip it + } + +TTimeIntervalMicroSeconds CVedMovieImp::VideoClipCutOutTime(TInt aIndex) const + { + return iVideoClipArray[aIndex]->CutOutTime(); + } + +void CVedMovieImp::VideoClipSetCutOutTime(TInt aIndex, TTimeIntervalMicroSeconds aCutOutTime) + { + iVideoClipArray[aIndex]->SetCutOutTime(aCutOutTime); + // basically we should call CalculatePropertiesL after this one, but since it is called in StartMovie, we can probably skip it + } + +TTimeIntervalMicroSeconds CVedMovieImp::VideoClipStartTime(TInt aIndex) const + { + return iVideoClipArray[aIndex]->StartTime(); + } + +TTimeIntervalMicroSeconds CVedMovieImp::VideoClipEndTime(TInt aIndex) const + { + return iVideoClipArray[aIndex]->EndTime(); + } + +TTimeIntervalMicroSeconds CVedMovieImp::VideoClipEditedDuration(TInt aIndex) const + { + return iVideoClipArray[aIndex]->EditedDuration(); + } + +CVedAudioClipInfo* CVedMovieImp::AudioClipInfo(TInt aIndex) const + { + return iAudioClipInfoArray[aIndex]; + } + +TTimeIntervalMicroSeconds CVedMovieImp::AudioClipStartTime(TInt aIndex) const + { + return iAudSong->Clip(aIndex, KVedAudioTrackIndex)->StartTime(); + } + +void CVedMovieImp::AudioClipSetStartTime(TInt aIndex, TTimeIntervalMicroSeconds aStartTime) + { + iAudSong->Clip(aIndex, KVedAudioTrackIndex)->SetStartTime(aStartTime); + } + +TTimeIntervalMicroSeconds CVedMovieImp::AudioClipEndTime(TInt aIndex) const + { + return iAudSong->Clip(aIndex, KVedAudioTrackIndex)->EndTime(); + } + +TTimeIntervalMicroSeconds CVedMovieImp::AudioClipEditedDuration(TInt aIndex) const + { + return iAudSong->Clip(aIndex, KVedAudioTrackIndex)->EditedDuration(); + } + +void CVedMovieImp::AudioClipSetCutInTime(TInt aIndex, TTimeIntervalMicroSeconds aCutInTime) + { + iAudSong->Clip(aIndex, KVedAudioTrackIndex)->SetCutInTime(aCutInTime); + } + +void CVedMovieImp::AudioClipSetCutOutTime(TInt aIndex, TTimeIntervalMicroSeconds aCutOutTime) + { + iAudSong->Clip(aIndex, KVedAudioTrackIndex)->SetCutOutTime(aCutOutTime); + } + + +TBool CVedMovieImp::AudioClipNormalizing(TInt aIndex) const + { + return iAudSong->Clip(aIndex, KVedAudioTrackIndex)->Normalizing(); + } + +void CVedMovieImp::AudioClipSetNormalizing(TInt aIndex, TBool aNormalizing) + { + iAudSong->Clip(aIndex, KVedAudioTrackIndex)->SetNormalizing(aNormalizing); + } + + +void CVedMovieImp::AudioClipInsertDynamicLevelMarkL(TInt aIndex, TVedDynamicLevelMark aMark) + { + __ASSERT_ALWAYS(aMark.iTime.Int64() >= 0, + TVedPanic::Panic(TVedPanic::EIllegalDynamicLevelMark)); + __ASSERT_ALWAYS(aMark.iTime.Int64() <= AudioClipCutOutTime(aIndex).Int64(), + TVedPanic::Panic(TVedPanic::EIllegalDynamicLevelMark)); + __ASSERT_ALWAYS(aIndex >= 0, + TVedPanic::Panic(TVedPanic::EVideoClipIllegalIndex)); + + iApplyDynamicLevelMark = ETrue; + iAudSong->Clip(aIndex, KVedAudioTrackIndex)->InsertDynamicLevelMarkL(TAudDynamicLevelMark(aMark.iTime, aMark.iLevel)); + } + +void CVedMovieImp::AudioClipRemoveDynamicLevelMark(TInt aClipIndex, TInt aMarkIndex) + { + __ASSERT_ALWAYS(aMarkIndex >= 0, + TVedPanic::Panic(TVedPanic::EIllegalDynamicLevelMarkIndex)); + __ASSERT_ALWAYS(aMarkIndex < AudioClipDynamicLevelMarkCount(aClipIndex), + TVedPanic::Panic(TVedPanic::EIllegalDynamicLevelMarkIndex)); + __ASSERT_ALWAYS(aClipIndex >= 0, + TVedPanic::Panic(TVedPanic::EVideoClipIllegalIndex)); + + iAudSong->Clip(aClipIndex, KVedAudioTrackIndex)->RemoveDynamicLevelMark(aMarkIndex); + } + +TInt CVedMovieImp::AudioClipDynamicLevelMarkCount(TInt aIndex) const + { + __ASSERT_ALWAYS(aIndex >= 0, + TVedPanic::Panic(TVedPanic::EVideoClipIllegalIndex)); + return iAudSong->Clip(aIndex, KVedAudioTrackIndex)->DynamicLevelMarkCount(); + } + +TVedDynamicLevelMark CVedMovieImp::AudioClipDynamicLevelMark(TInt aClipIndex, TInt aMarkIndex) + { + __ASSERT_ALWAYS(aMarkIndex >= 0, + TVedPanic::Panic(TVedPanic::EIllegalDynamicLevelMarkIndex)); + __ASSERT_ALWAYS(aMarkIndex < AudioClipDynamicLevelMarkCount(aClipIndex), + TVedPanic::Panic(TVedPanic::EIllegalDynamicLevelMarkIndex)); + __ASSERT_ALWAYS(aClipIndex >= 0, + TVedPanic::Panic(TVedPanic::EVideoClipIllegalIndex)); + + CAudClip* clip = iAudSong->Clip(aClipIndex, KVedAudioTrackIndex); + TAudDynamicLevelMark mark(clip->DynamicLevelMark(aMarkIndex)); + return TVedDynamicLevelMark(mark.iTime, mark.iLevel); + } + + +void CVedMovieImp::SetVideoClipVolumeGainL(TInt aClipIndex, TInt aVolumeGain) + { + iApplyDynamicLevelMark = EFalse; + + TInt marks = 0; + if (aClipIndex == KVedClipIndexAll) + { + // whole movie, sum with clip values in SetAudioFadingL + iVolumeGainForAllVideoClips = aVolumeGain; + marks = 1; + } + else + { + __ASSERT_ALWAYS(aClipIndex >= 0, + TVedPanic::Panic(TVedPanic::EVideoClipIllegalIndex)); + __ASSERT_ALWAYS(aClipIndex <= VideoClipCount(), + TVedPanic::Panic(TVedPanic::EVideoClipIllegalIndex)); + // set volume gain to the clip + CVedVideoClip* clip = iVideoClipArray[aClipIndex]; + clip->SetVolumeGain(aVolumeGain); + + // should also add/remove a dynamic level mark to have the observer calls more meaningful + // and avoid problems if client assumes a mark was really added + // the actual mark is removed when starting to process + if ( aVolumeGain != 0 ) + { + // add + clip->InsertDynamicLevelMarkL(TVedDynamicLevelMark(clip->CutInTime(),aVolumeGain)); + clip->InsertDynamicLevelMarkL(TVedDynamicLevelMark(clip->CutOutTime(),aVolumeGain)); + } + else + { + // gain == 0 => remove marks + while (clip->DynamicLevelMarkCount() > 0) + { + marks++; + clip->RemoveDynamicLevelMark(0); + } + } + } + + // inform observers + if ( aVolumeGain == 0 ) + { + // volume gain was set to 0 => no gain ~= remove level mark + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + for ( TInt j = 0; j < marks; j++ ) + { + iObserverArray[i]->NotifyVideoClipDynamicLevelMarkRemoved(*this, aClipIndex,0); + } + } + } + else + { + // volume gain was set to nonzero => gain ~= insert level mark + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyVideoClipDynamicLevelMarkInserted(*this, aClipIndex, 0); + iObserverArray[i]->NotifyVideoClipDynamicLevelMarkInserted(*this, aClipIndex, 1); + } + } + } + +TInt CVedMovieImp::GetVideoClipVolumeGainL(TInt aClipIndex) + { + if (aClipIndex == KVedClipIndexAll) + { + return iVolumeGainForAllVideoClips; + } + else + { + // get volume gain from the clip + __ASSERT_ALWAYS(aClipIndex >= 0, + TVedPanic::Panic(TVedPanic::EVideoClipIllegalIndex)); + __ASSERT_ALWAYS(aClipIndex <= VideoClipCount(), + TVedPanic::Panic(TVedPanic::EVideoClipIllegalIndex)); + return iVideoClipArray[aClipIndex]->GetVolumeGain(); + } + } + +void CVedMovieImp::SetAudioClipVolumeGainL(TInt aClipIndex, TInt aVolumeGain) + { + iApplyDynamicLevelMark = EFalse; + TInt marks = 0; + if (aClipIndex == KVedClipIndexAll) + { + // whole movie, sum with clip values in SetAudioFading + iVolumeGainForAllAudioClips = aVolumeGain; + marks = 1; + } + else + { + // set volume gain to the clip; the clip asserts the index + CAudClip* clip = iAudSong->Clip(aClipIndex, KVedAudioTrackIndex); + clip->SetVolumeGain(aVolumeGain); + + // should also add/remove a dynamic level mark to have the observer calls more meaningful + // and avoid problems if client assumes a mark was really added + // the actual mark is removed when starting to process + if ( aVolumeGain != 0 ) + { + // add + clip->InsertDynamicLevelMarkL(TAudDynamicLevelMark(clip->CutInTime(),aVolumeGain)); + clip->InsertDynamicLevelMarkL(TAudDynamicLevelMark(clip->CutOutTime(),aVolumeGain)); + } + else + { + // gain == 0 => remove + while (clip->DynamicLevelMarkCount() > 0) + { + marks++; + clip->RemoveDynamicLevelMark(0); + } + } + } + + // inform observers + if ( aVolumeGain == 0 ) + { + // volume gain was set to 0 => no gain ~= remove level mark + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + for ( TInt j = 0; j < marks; j++ ) + { + iObserverArray[i]->NotifyAudioClipDynamicLevelMarkRemoved(*this, aClipIndex,0); + } + } + } + else + { + // volume gain was set to nonzero => gain ~= insert level mark + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyAudioClipDynamicLevelMarkInserted(*this, aClipIndex,0); + } + } + } + +TInt CVedMovieImp::GetAudioClipVolumeGainL(TInt aClipIndex) + { + if (aClipIndex == KVedClipIndexAll) + { + return iVolumeGainForAllAudioClips; + } + else + { + // get volume gain from the clip; the clip asserts the index + CAudClip* clip = iAudSong->Clip(aClipIndex, KVedAudioTrackIndex); + return clip->GetVolumeGain(); + } + } + + +TRgb CVedMovieImp::VideoClipColorTone(TInt aVideoClipIndex) const + { + return iVideoClipArray[aVideoClipIndex]->ColorTone(); + } + +void CVedMovieImp::VideoClipSetColorTone(TInt aVideoClipIndex, TRgb aColorTone) + { + iVideoClipArray[aVideoClipIndex]->SetColorTone(aColorTone); + } + + +TTimeIntervalMicroSeconds CVedMovieImp::Duration() const + { + TTimeIntervalMicroSeconds duration = TTimeIntervalMicroSeconds(0); + + if (VideoClipCount() > 0) + { + duration = iVideoClipArray[VideoClipCount() - 1]->EndTime(); + } + + for (TInt i = 0; i < AudioClipCount(); i++) + { + TTimeIntervalMicroSeconds endTime = iAudSong->Clip(i, KVedAudioTrackIndex)->EndTime(); + if (endTime > duration) + { + duration = endTime; + } + } + + return duration; + } + + +TInt CVedMovieImp::VideoClipCount() const + { + return iVideoClipArray.Count(); + } + + +CVedVideoClip* CVedMovieImp::VideoClip(TInt aClipIndex) const + { + return iVideoClipArray[aClipIndex]; + } + + +TVedStartTransitionEffect CVedMovieImp::StartTransitionEffect() const + { + __ASSERT_ALWAYS(VideoClipCount() > 0, TVedPanic::Panic(TVedPanic::EMovieEmpty)); + return iStartTransitionEffect; + } + + +TInt CVedMovieImp::MiddleTransitionEffectCount() const + { + return Max(0, iVideoClipArray.Count() - 1); + } + + +TVedMiddleTransitionEffect CVedMovieImp::MiddleTransitionEffect(TInt aIndex) const + { + if (aIndex == (iVideoClipArray.Count() - 1)) + { + aIndex++; // make aIndex out of range to cause panic + } + + return iVideoClipArray[aIndex]->iMiddleTransitionEffect; + } + + +TVedEndTransitionEffect CVedMovieImp::EndTransitionEffect() const + { + __ASSERT_ALWAYS(VideoClipCount() > 0, TVedPanic::Panic(TVedPanic::EMovieEmpty)); + return iEndTransitionEffect; + } + + +TInt CVedMovieImp::AudioClipCount() const + { + return iAudSong->ClipCount(KVedAudioTrackIndex); + } + +TTimeIntervalMicroSeconds CVedMovieImp::AudioClipCutInTime(TInt aIndex) const + { + return iAudSong->Clip(aIndex, KVedAudioTrackIndex)->CutInTime(); + } + +TTimeIntervalMicroSeconds CVedMovieImp::AudioClipCutOutTime(TInt aIndex) const + { + return iAudSong->Clip(aIndex, KVedAudioTrackIndex)->CutOutTime(); + } + + + +void CVedMovieImp::FireVideoClipAdded(CVedMovie* aMovie, CVedVideoClip* aClip) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyVideoClipAdded(*aMovie, aClip->Index()); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + + +void CVedMovieImp::FireVideoClipAddingFailed(CVedMovie* aMovie, TInt aError) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyVideoClipAddingFailed(*aMovie, aError); + } + } + + +void CVedMovieImp::FireVideoClipRemoved(CVedMovie* aMovie, TInt aIndex) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyVideoClipRemoved(*aMovie, aIndex); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + + +void CVedMovieImp::FireVideoClipIndicesChanged(CVedMovie* aMovie, TInt aOldIndex, + TInt aNewIndex) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyVideoClipIndicesChanged(*aMovie, aOldIndex, aNewIndex); + } + } + + +void CVedMovieImp::FireVideoClipTimingsChanged(CVedMovie* aMovie, CVedVideoClip* aClip) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyVideoClipTimingsChanged(*aMovie, aClip->Index()); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + + +void CVedMovieImp::FireVideoClipColorEffectChanged(CVedMovie* aMovie, CVedVideoClip* aClip) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyVideoClipColorEffectChanged(*aMovie, aClip->Index()); + } + } + + +void CVedMovieImp::FireVideoClipAudioSettingsChanged(CVedMovie* aMovie, CVedVideoClip* aClip) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyVideoClipAudioSettingsChanged(*aMovie, aClip->Index()); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + + +void CVedMovieImp::FireVideoClipGeneratorSettingsChanged(CVedMovie* aMovie, CVedVideoClip* aClip) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyVideoClipGeneratorSettingsChanged(*aMovie, aClip->Index()); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + +void CVedMovieImp::FireVideoClipDescriptiveNameChanged(CVedMovie* aMovie, CVedVideoClip* aClip) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyVideoClipDescriptiveNameChanged(*aMovie, aClip->Index()); + } + } + +void CVedMovieImp::FireStartTransitionEffectChanged(CVedMovie* aMovie) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyStartTransitionEffectChanged(*aMovie); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + + +void CVedMovieImp::FireMiddleTransitionEffectChanged(CVedMovie* aMovie, TInt aIndex) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyMiddleTransitionEffectChanged(*aMovie, aIndex); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + + +void CVedMovieImp::FireEndTransitionEffectChanged(CVedMovie* aMovie) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyEndTransitionEffectChanged(*aMovie); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + + +void CVedMovieImp::FireAudioClipAdded(CVedMovie* aMovie, TInt aIndex) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyAudioClipAdded(*aMovie, aIndex); + } + + TRAPD(err,CalculatePropertiesL());// ignore error? + if (err != KErrNone) { } + + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + + +void CVedMovieImp::FireAudioClipAddingFailed(CVedMovie* aMovie, TInt aError) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyAudioClipAddingFailed(*aMovie, aError); + } + } + + +void CVedMovieImp::FireAudioClipRemoved(CVedMovie* aMovie, TInt aIndex) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyAudioClipRemoved(*aMovie, aIndex); + } + + TRAPD(err,CalculatePropertiesL());// ignore error? + if (err != KErrNone) { } + + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + + +void CVedMovieImp::FireAudioClipIndicesChanged(CVedMovie* aMovie, TInt aOldIndex, TInt aNewIndex) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyAudioClipIndicesChanged(*aMovie, + aOldIndex, aNewIndex); + } + } + + +void CVedMovieImp::FireAudioClipTimingsChanged(CVedMovie* aMovie, CAudClip* aClip) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyAudioClipTimingsChanged(*aMovie, aClip->IndexOnTrack()); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + + +void CVedMovieImp::FireDynamicLevelMarkRemoved(CAudClip& aClip, TInt aMarkIndex) + { + TInt trackIndex = aClip.TrackIndex(); + TInt clipIndex = aClip.IndexOnTrack(); + + if (!iNotifyObserver) + return; + + if (trackIndex == 0) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyVideoClipDynamicLevelMarkRemoved(*this, clipIndex, aMarkIndex); + } + } + else if (trackIndex == 1) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyAudioClipDynamicLevelMarkRemoved(*this, clipIndex, aMarkIndex); + } + } + else + { + TVedPanic::Panic(TVedPanic::EInternal); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + +void CVedMovieImp::FireDynamicLevelMarkInserted(CAudClip& aClip, TAudDynamicLevelMark& /*aMark*/, TInt aMarkIndex) + { + TInt trackIndex = aClip.TrackIndex(); + TInt clipIndex = aClip.IndexOnTrack(); + + if (!iNotifyObserver) + return; + + if (trackIndex == 0) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyVideoClipDynamicLevelMarkInserted(*this, clipIndex, aMarkIndex); + } + } + else if (trackIndex == 1) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyAudioClipDynamicLevelMarkInserted(*this, clipIndex, aMarkIndex); + } + } + else + { + TVedPanic::Panic(TVedPanic::EInternal); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + + +void CVedMovieImp::FireMovieQualityChanged(CVedMovie* aMovie) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyMovieQualityChanged(*aMovie); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + + +void CVedMovieImp::FireMovieOutputParametersChanged(CVedMovie* aMovie) + { + + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyMovieOutputParametersChanged(*aMovie); + } + // reset the estimated processing time + iEstimatedProcessingTime = TTimeIntervalMicroSeconds(0); + } + +void CVedMovieImp::FireMovieReseted(CVedMovie* aMovie) + { + for (TInt i = 0; i < iObserverArray.Count(); i++) + { + iObserverArray[i]->NotifyMovieReseted(*aMovie); + } + } + + +void CVedMovieImp::ProcessL(const TDesC& aFileName, + MVedMovieProcessingObserver& aObserver) + { + __ASSERT_ALWAYS((VideoClipCount() > 0) || (AudioClipCount() > 0), + TVedPanic::Panic(TVedPanic::EMovieEmpty)); + + CalculatePropertiesL(); + iAudSong->SetDuration(Duration()); + SetAudioFadingL(); + + iMovieProcessingObserver = &aObserver; + + iProcessor->StartMovieL(this, aFileName, NULL, &aObserver); + } + +void CVedMovieImp::ProcessL(RFile* aFileHandle, + MVedMovieProcessingObserver& aObserver) + { + __ASSERT_ALWAYS((VideoClipCount() > 0) || (AudioClipCount() > 0), + TVedPanic::Panic(TVedPanic::EMovieEmpty)); + + CalculatePropertiesL(); + iAudSong->SetDuration(Duration()); + SetAudioFadingL(); + + iMovieProcessingObserver = &aObserver; + TFileName dummy; + + iProcessor->StartMovieL(this, dummy, aFileHandle, &aObserver); + } + + +void CVedMovieImp::CancelProcessing() + { + TRAPD(error, iProcessor->CancelProcessingL()); + + if (error != KErrNone) + iMovieProcessingObserver->NotifyMovieProcessingCompleted(*this, error); + + } + +void CVedMovieImp::SetMovieSizeLimit(TInt aLimit) + { + iProcessor->SetMovieSizeLimit(aLimit); + } + +TInt CVedMovieImp::SyncIntervalInPicture() + { + return iSyncIntervalInPicture; + } + +TReal CVedMovieImp::RandomAccessRate() + { + return iRandomAccessRate; + } + +// Create a temporary transcoder instance and ask for transcoding time factor for the given settings +TReal CVedMovieImp::AskComplexityFactorFromTranscoderL(CVedVideoClipInfo* aInfo, CTRTranscoder::TTROperationalMode aMode, TReal aInputFrameRate) + { + PRINT((_L("CVedMovieImp::AskComplexityFactorFromTranscoderL() in"))); + TReal complexityFactor; + CTRTranscoder *tmpTranscoder; + TTRVideoFormat formIn; + TTRVideoFormat formOut; + formIn.iSize = aInfo->Resolution(); + formIn.iDataType = CTRTranscoder::ETRDuCodedPicture; + formOut.iSize = iResolution; + formOut.iDataType = CTRTranscoder::ETRDuCodedPicture; + TBufC8<255> inputMime; + MapVideoCodecTypeToMime(aInfo->VideoType(), inputMime); + + // create temporary transcoder observer object, with input framerate as parameter, since it is asked by the transcoder + CTrObs* tmpObs = new (ELeave) CTrObs(aInputFrameRate); + CleanupStack::PushL(tmpObs); + + // create temporary transcoder instance + tmpTranscoder = CTRTranscoder::NewL(*tmpObs); + CleanupStack::PushL(tmpTranscoder); + tmpTranscoder->OpenL(reinterpret_cast(1),//the sink will not be used, hence this is acceptable + aMode, + inputMime, + iVideoCodecMimeType, + formIn, + formOut, + EFalse ); + + // ask complexity/time factor from the transcoder + complexityFactor = tmpTranscoder->EstimateTranscodeTimeFactorL(formIn, formOut); + + CleanupStack::PopAndDestroy(tmpTranscoder); + CleanupStack::PopAndDestroy(tmpObs); + + PRINT((_L("CVedMovieImp::AskComplexityFactorFromTranscoderL() out, complexity factor %f"), complexityFactor)); + return complexityFactor; + } + + +TTimeIntervalMicroSeconds CVedMovieImp::GetProcessingTimeEstimateL() + { + PRINT((_L("CVedMovieImp::GetProcessingTimeEstimateL() in"))); + TInt64 estimatedTime = 0; + TReal complexityFactor; + TBool transcodingImpactIncluded = EFalse; + + // Don't estimate the time if it has been asked already. + // This also means the result is not the remaining time but the total processing time + if ( iEstimatedProcessingTime > 0 ) + { + return iEstimatedProcessingTime; + } + + + // Loop through the clips in the movie and estimate the processing time for each of them + for (TInt i = 0; i < VideoClipCount(); i++) + { + CVedVideoClipInfo* currentInfo = VideoClip(i)->Info(); + + complexityFactor = 0; + transcodingImpactIncluded = EFalse; + + if ( currentInfo->Class() == EVedVideoClipClassGenerated ) + { + // only encoding for generated content. Framerate is low. + transcodingImpactIncluded = ETrue; + + // open transcoder in encoding mode & ask the factor. + // This is in practice for generated content only. Tbd if it is worth opening the transcoder? + complexityFactor = AskComplexityFactorFromTranscoderL(currentInfo, CTRTranscoder::EEncoding, 1.0); + // the temporary clip is then processed like a normal input clip, add the impact + complexityFactor += (KVedBitstreamProcessingFactor*iVideoStandardBitrate) / KVedBitstreamProcessingFactorBitrate; + } + else + { + // check if transcoding is needed + + // If input and output resolutions don't match, transcoder knows it need to do resolution transcoding + // However, we need to check here in which mode we'd open the transcoder + if ((currentInfo->Resolution() != iResolution) || (iVideoRestrictedBitrate != 0) + || ((currentInfo->VideoType() == EVedVideoTypeH263Profile0Level45) && (iVideoType == EVedVideoTypeH263Profile0Level10))) + { + // need to do resolution transcoding + transcodingImpactIncluded = ETrue; + + // open transcoder in full transcoding mode & ask for the factor. + TReal framerate = TReal(1000*currentInfo->VideoFrameCount())/(currentInfo->Duration().Int64()/1000); + complexityFactor = AskComplexityFactorFromTranscoderL(currentInfo, CTRTranscoder::EFullTranscoding, framerate); + } + else + { + // no full transcoding + + if ( currentInfo->VideoType() != iVideoType ) + { + // compressed domain transcoding between H.263 and MPEG-4. Assuming they are equally complex + + complexityFactor = (KVedCompressedDomainTranscodingFactor * iVideoStandardBitrate) / KVedBitstreamProcessingFactorBitrate; + } + else + { + // Only bitstream processing + possibly cut or some other simple operation. Transition effect is estimated later + // It is assumed that pure decoding is needed only for such a short period of time that + // the impact can be estimated here without opening processor/transcoder. + + // Bitrate has impact here. MPEG-4 is more complex to process than H.263 but bitrate is dominant. E,g, H.263 128 kbps vs MPEG4 512 kbps: 1:5 complexity; 1:4 bitrate + complexityFactor = (KVedBitstreamProcessingFactor*iVideoStandardBitrate) / KVedBitstreamProcessingFactorBitrate; + } + + } + } + + // Now we have the video complexity factor for the current clip. Add the contribution to the total time + estimatedTime = estimatedTime + TInt64(complexityFactor * I64INT(VideoClip(i)->EditedDuration().Int64())); + + if (!transcodingImpactIncluded && (VideoClip(i)->iMiddleTransitionEffect != EVedMiddleTransitionEffectNone)) + { + // add impact of transition effect; need decoding + encoding for a short period + + // open transcoder in full transcoding mode & ask for the factor. + TReal framerate = TReal(1000*currentInfo->VideoFrameCount())/(currentInfo->Duration().Int64()/1000); + complexityFactor = this->AskComplexityFactorFromTranscoderL(currentInfo, CTRTranscoder::EFullTranscoding, framerate); + estimatedTime = estimatedTime + TInt64(complexityFactor * 1000000);//transition duration; 1 sec is accurate enough here + } + + } + + PRINT((_L("CVedMovieImp::GetProcessingTimeEstimateL(), video part estimated to %d sec"),I64INT(estimatedTime)/1000000 )); + + // add audio processing time + estimatedTime = estimatedTime + iAudSong->GetTimeEstimateL().Int64(); + + PRINT((_L("CVedMovieImp::GetProcessingTimeEstimateL(), audio included, before rounding the estimate is %d sec"),I64INT(estimatedTime)/1000000 )); + // estimate is not too accurate anyway; round it + if ( estimatedTime > 600000000 ) + { + // more than 10 minutes => round to nearest 2 min + estimatedTime = ((estimatedTime+60000000) / 120000000) * 120000000; + } + else if (estimatedTime > 120000000 ) + { + // more than 2 minutes => round to nearest 30 sec + estimatedTime = ((estimatedTime+30000000) / 30000000) * 30000000; + } + else if (estimatedTime > 30000000 ) + { + // more than 30 secs => round to nearest 10 sec + estimatedTime = ((estimatedTime+5000000) / 10000000) * 10000000; + } + else + { + // less than 30 secs => round to nearest 2 sec + estimatedTime = ((estimatedTime+1000000) / 2000000) * 2000000; + } + + iEstimatedProcessingTime = estimatedTime; + PRINT((_L("CVedMovieImp::GetProcessingTimeEstimateL() out, estimate is %d sec"),I64INT(estimatedTime)/1000000 )); + return estimatedTime; + + } + + +void CVedMovieImp::NotifyClipAdded(CAudSong& aSong, CAudClip& aClip, TInt aIndex, TInt aTrackIndex) + { + PRINT((_L("CVedMovieImp::NotifyClipAdded() in") )); + // Track index 0 means it's the video track - we need to create the video clip + if (aTrackIndex == 0) + { + PRINT((_L("CVedMovieImp::NotifyClipAdded() added audio track of video clip to song successfully") )); + + TInt err; + if (iAddedVideoClipFileHandle) + { + TRAP(err, iAddOperation->iVideoClip = CVedVideoClip::NewL(this, aClip.Info()->FileHandle(), iAddedVideoClipIndex, &aClip, *iAddOperation)); + } + else + { + TRAP(err, iAddOperation->iVideoClip = CVedVideoClip::NewL(this, aClip.Info()->FileName(), iAddedVideoClipIndex, &aClip, *iAddOperation)); + } + + if (err != KErrNone) + { + PRINT((_L("CVedMovieImp::NotifyClipAdded() creating video clip failed, removing also audio") )); + // delete the audio clip from song + aSong.RemoveClip(aIndex); + + FireVideoClipAddingFailed(this, err); + } + delete iAddedVideoClipFilename; + iAddedVideoClipFilename = 0; + iAddedVideoClipFileHandle = 0; + } + else if (aTrackIndex == KVedAudioTrackIndex) + { + // We're on the audio track so we need to create an audio clip info + PRINT((_L("CVedMovieImp::NotifyClipAdded() added audio track of audio clip to song successfully") )); + CVedAudioClipInfoImp* audioClipInfo = 0; + TRAPD(err, audioClipInfo = CVedAudioClipInfoImp::NewL(&aClip, *this)); + if (err != KErrNone) + { + delete audioClipInfo; + FireAudioClipAddingFailed(this, err); + return; + } + err = iAudioClipInfoArray.Insert(audioClipInfo, aIndex); + if (err != KErrNone) + { + delete audioClipInfo; + FireAudioClipAddingFailed(this, err); + } + } + PRINT((_L("CVedMovieImp::NotifyClipAdded() out") )); + } + +void CVedMovieImp::NotifyClipAddingFailed(CAudSong& /*aSong*/, TInt aError, TInt aTrackIndex) + { + if (aTrackIndex == 0) + { + if (aError == KErrNoAudio) + { + // We can have video clips that have no audio track + + TInt err; + if (iAddedVideoClipFileHandle) + { + TRAP(err, iAddOperation->iVideoClip = CVedVideoClip::NewL(this, iAddedVideoClipFileHandle, iAddedVideoClipIndex, NULL, *iAddOperation)); + } + else + { + TRAP(err, iAddOperation->iVideoClip = CVedVideoClip::NewL(this, *iAddedVideoClipFilename, iAddedVideoClipIndex, NULL, *iAddOperation)); + } + if (err != KErrNone) + { + FireAudioClipAddingFailed(this, aError); + } + } + else + { + FireVideoClipAddingFailed(this, aError); + } + + delete iAddedVideoClipFilename; + iAddedVideoClipFilename = 0; + } + else if (aTrackIndex == KVedAudioTrackIndex) + { + FireAudioClipAddingFailed(this, aError); + } + } + +void CVedMovieImp::NotifyClipRemoved(CAudSong& /*aSong*/, TInt aIndex, TInt aTrackIndex) + { + if (aTrackIndex == KVedAudioTrackIndex) + { + CVedAudioClipInfoImp* info = iAudioClipInfoArray[aIndex]; + delete info; + iAudioClipInfoArray.Remove(aIndex); + FireAudioClipRemoved(this, aIndex); + } + } + +void CVedMovieImp::NotifyClipTimingsChanged(CAudSong& /*aSong*/, CAudClip& aClip) + { + if (aClip.TrackIndex() == KVedAudioTrackIndex) + { + FireAudioClipTimingsChanged(this, &aClip); + } + } + +void CVedMovieImp::NotifyClipIndicesChanged(CAudSong& /*aSong*/, TInt aOldIndex, TInt aNewIndex, TInt aTrackIndex) + { + if (aTrackIndex == KVedAudioTrackIndex) + { + TLinearOrder order(CVedAudioClipInfoImp::Compare); + iAudioClipInfoArray.Sort(order); + FireAudioClipIndicesChanged(this, aOldIndex, aNewIndex); + } + } + +void CVedMovieImp::NotifySongReseted(CAudSong& /*aSong*/) + { + // nothing to do here + } + +void CVedMovieImp::NotifyClipReseted(CAudClip& /*aClip*/) + { + // nothing to do here + } + +void CVedMovieImp::NotifyDynamicLevelMarkInserted(CAudClip& aClip, TAudDynamicLevelMark& aMark, TInt aIndex) + { + FireDynamicLevelMarkInserted(aClip, aMark, aIndex); + } + +void CVedMovieImp::NotifyDynamicLevelMarkRemoved(CAudClip& aClip, TInt aIndex) + { + FireDynamicLevelMarkRemoved(aClip, aIndex); + } + + +void CVedMovieImp::NotifyAudioClipInfoReady(CVedAudioClipInfo& aInfo, TInt aError) + { + if (aError != KErrNone) + { + iAudioClipInfoArray.Remove(iAudioClipInfoArray.Count() - 1); + FireAudioClipAddingFailed(this, aError); + } + else + { + CVedAudioClipInfoImp* infoImp = static_cast (&aInfo); + FireAudioClipAdded(this, infoImp->iAudClip->IndexOnTrack()); + } + } + +CAudSong* CVedMovieImp::Song() + { + return iAudSong; + } + +TPtrC8& CVedMovieImp::VideoCodecMimeType() + { + return iVideoCodecMimeType; + } + + +CVedMovieAddClipOperation* CVedMovieAddClipOperation::NewL(CVedMovie* aMovie) + { + PRINT(_L("CVedMovieAddClipOperation::NewL")); + + CVedMovieAddClipOperation* self = + new (ELeave) CVedMovieAddClipOperation(aMovie); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +CVedMovieAddClipOperation::CVedMovieAddClipOperation(CVedMovie* aMovie) + : CActive(EPriorityStandard), iMovie((CVedMovieImp*)aMovie) + { + + CActiveScheduler::Add(this); + } + + +void CVedMovieAddClipOperation::ConstructL() + { + } + + +CVedMovieAddClipOperation::~CVedMovieAddClipOperation() + { + Cancel(); + + if (iVideoClip) + { + delete iVideoClip; + iVideoClip = NULL; + } + } + + +void CVedMovieAddClipOperation::NotifyVideoClipInfoReady(CVedVideoClipInfo& /*aInfo*/, + TInt aError) + { + + // Cannot delete iVideoClip here, since we are in its callback function, + // so schedule the active object to complete the add operation and + // delete iVideoClip if needed. + + iError = aError; + + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } +void CVedMovieAddClipOperation::RunL() + { + __ASSERT_DEBUG((iVideoClip != 0), + TVedPanic::Panic(TVedPanic::EInternal)); + + if (iVideoClip != 0) + { + CompleteAddVideoClipOperation(); + } + + __ASSERT_DEBUG(iVideoClip == 0, + TVedPanic::Panic(TVedPanic::EInternal)); + } + + +void CVedMovieAddClipOperation::DoCancel() + { + if (iVideoClip) + { + if (iVideoClip->EditedHasAudio()) + { + TInt audioClipIndex = iVideoClip->iAudClip->IndexOnTrack(); + iMovie->iAudSong->RemoveClip(audioClipIndex, 0); + } + delete iVideoClip; + iVideoClip = NULL; + iMovie->FireVideoClipAddingFailed(iMovie, KErrCancel); + } + } + + +void CVedMovieAddClipOperation::CompleteAddVideoClipOperation() + { + if (iError != KErrNone) + { + if (iVideoClip->EditedHasAudio()) + { + TInt audioClipIndex = iVideoClip->iAudClip->IndexOnTrack(); + iMovie->iAudSong->RemoveClip(audioClipIndex, 0); + } + delete iVideoClip; + iVideoClip = 0; + iMovie->FireVideoClipAddingFailed(iMovie, iError); + } + else + { + TInt insertableError = iMovie->CheckVideoClipInsertable(iVideoClip); + + if (insertableError != KErrNone) + { + if (iVideoClip->EditedHasAudio()) + { + TInt audioClipIndex = iVideoClip->iAudClip->IndexOnTrack(); + iMovie->iAudSong->RemoveClip(audioClipIndex, 0); + } + delete iVideoClip; + iVideoClip = 0; + iMovie->FireVideoClipAddingFailed(iMovie, insertableError); + } + else + { + iVideoClip->iMiddleTransitionEffect = EVedMiddleTransitionEffectNone; + + if (iVideoClip->iInfo->Class() == EVedVideoClipClassFile) + { + iVideoClip->iCutOutTime = iVideoClip->iInfo->Duration(); + } + else + { + iVideoClip->iCutOutTime = TTimeIntervalMicroSeconds(0); + } + + TInt err = iMovie->iVideoClipArray.Insert(iVideoClip, iVideoClip->iIndex); + if (err != KErrNone) + { + if (iVideoClip->EditedHasAudio()) + { + // delete corresponding audio clip from song + TInt audioClipIndex = iVideoClip->iAudClip->IndexOnTrack(); + iMovie->iAudSong->RemoveClip(audioClipIndex, 0); + } + delete iVideoClip; + iVideoClip = 0; + iMovie->FireVideoClipAddingFailed(iMovie, err); + } + else + { + if (iVideoClip->iInfo->Class() == EVedVideoClipClassGenerated) + { + iVideoClip->iInfo->Generator()->SetVideoClip(*iVideoClip, + iIsVideoGeneratorOwnedByVideoClip); + } + + iMovie->RecalculateVideoClipTimings(iVideoClip); + TRAPD(err,iMovie->CalculatePropertiesL());//ignore error, should not leave with current implementation + if (err != KErrNone) { } + + CVedVideoClip* clip = iVideoClip; + iVideoClip = 0; + iMovie->FireVideoClipAdded(iMovie, clip); + } + } + } + } + +