--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmserv/thumbnailengine/TneProcessorSrc/TNEDecoderWrap.cpp Tue Feb 02 01:08:46 2010 +0200
@@ -0,0 +1,1077 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: TNE decoder wrapper
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include <devvideoconstants.h>
+#include "TNEDecoderWrap.h"
+#include "ctrsettings.h"
+
+// MACROS
+#define TRASSERT(x) __ASSERT_DEBUG(x, User::Panic(_L("CTRANSCODERVIDEODECODERCLIENT"), -10010))
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CTNEDecoderWrap* CTNEDecoderWrap::NewL(MThumbnailObserver* aObserver)
+{
+ PRINT((_L("CTNEDecoderWrap::NewL(), In")))
+ CTNEDecoderWrap* self = new (ELeave) CTNEDecoderWrap(aObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ PRINT((_L("CTNEDecoderWrap::NewL(), Out")))
+ return self;
+}
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::CTNEDecoderWrap
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CTNEDecoderWrap::CTNEDecoderWrap(MThumbnailObserver* aObserver)
+{
+ iObserver = aObserver;
+ iDevVideoPlay = NULL;
+ iCompresedFormat = NULL;
+ iClockSource = NULL;
+ iUid = TUid::Null();
+ iHwDeviceId = THwDeviceId(0);
+ iInputBuffer = NULL;
+ iCodedBuffer = NULL;
+ iDecodedPicture = NULL;
+ iFatalError = KErrNone;
+ iDataUnitType = EDuCodedPicture;
+ iStop = EFalse;
+ iState = ETRNone;
+ iLastTimestamp = -1;
+}
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::ConstructL()
+{
+ iDevVideoPlay = CMMFDevVideoPlay::NewL(*this);
+
+ // Support for AVC
+ iClockSource = CSystemClockSource::NewL();
+ iInputFrameNum = 1;
+}
+
+
+// ---------------------------------------------------------
+// CTNEDecoderWrap::~CTNEDecoderWrap()
+// Destructor
+// ---------------------------------------------------------
+//
+CTNEDecoderWrap::~CTNEDecoderWrap()
+{
+ PRINT((_L("CTNEDecoderWrap::~CTNEDecoderWrap(), In")))
+
+ if (iDevVideoPlay)
+ {
+ delete iDevVideoPlay;
+ iDevVideoPlay = NULL;
+ }
+
+ iInputBuffer = NULL;
+
+ if (iClockSource)
+ {
+ delete iClockSource;
+ iClockSource = 0;
+ }
+
+
+ if (iCompresedFormat)
+ {
+ delete iCompresedFormat;
+ }
+
+ iAcceleratedDecoders.Reset();
+ iAcceleratedDecoders.Close();
+
+ PRINT((_L("CTNEDecoderWrap::~CTNEDecoderWrap(), Out")))
+}
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::SupportsCodec
+// Checks whether this coded is supported
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CTNEDecoderWrap::SupportsCodec(const TDesC8& aFormat, const TDesC8& aShortFormat)
+{
+ TBool supports = EFalse;
+ TBuf8<256> mime;
+
+ if (iDevVideoPlay)
+ {
+ RArray<TUid> decoders;
+
+ TRAPD( status, iDevVideoPlay->FindDecodersL(aShortFormat, 0/*aPreProcType*/, decoders, EFalse/*aExactMatch*/) );
+
+ if( ( status != KErrNone ) || ( decoders.Count() <= 0 ) )
+ {
+ PRINT((_L("CTNEDecoderWrap::SupportsCodec(), status[%d]"), status))
+ supports = EFalse;
+ }
+ else
+ {
+ // Keep mime type given by codec fo future use
+ iMimeType = aFormat;
+ iShortMimeType = aShortFormat;
+ supports = ETrue;
+ }
+
+ decoders.Reset();
+ decoders.Close();
+ }
+
+ return supports;
+}
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::SetDecoderParametersL
+// Sets codec parameters
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::SetDecoderParametersL(TInt aDecoderLevel, const TTRVideoFormat& aFormat)
+{
+ PRINT((_L("CTNEDecoderWrap::SetDecoderParametersL(), In")))
+ RArray<TUid> decoders;
+ TBool codecAcceleration = EFalse;
+ TInt status = KErrNone;
+ iCodecLevel = aDecoderLevel;
+ iFormat = aFormat;
+
+ // Find the list of decoders
+ iDevVideoPlay->FindDecodersL(iShortMimeType, 0/*aPreProcType*/, decoders, EFalse/*aExactMatch*/);
+
+ // Input format
+ if (!iCompresedFormat)
+ {
+ TRAP(status, iCompresedFormat = CCompressedVideoFormat::NewL( iMimeType ));
+
+ if (status != KErrNone)
+ {
+ // Reset decoder's list
+ decoders.Reset();
+ decoders.Close();
+ User::Leave(status);
+ }
+ }
+
+ // get decoder info
+ for ( TInt i = 0; i < decoders.Count(); i ++ )
+ {
+ TRAP( status, codecAcceleration = CheckDecoderInfoL(decoders[i]) );
+
+ if (status == KErrNone)
+ {
+ if (codecAcceleration != KTRAccelerationPriorityDecoder)
+ {
+ // Use the first available software decoder
+ iUid = decoders[i];
+
+ // Keep the list of non-checked codecs for future use
+ i = i + 1;
+ for (; i < decoders.Count(); i ++)
+ {
+ iCheckDecoders.Insert(decoders[i], iCheckDecoders.Count() );
+ }
+
+ break;
+ }
+ else
+ {
+ // Keep track of accelerated decoder to the list of "good" decoders
+ iAcceleratedDecoders.Insert( decoders[i], iAcceleratedDecoders.Count() );
+ }
+ }
+ }
+
+ decoders.Reset();
+ decoders.Close();
+
+ if (iUid == TUid::Null())
+ {
+ // Check others "good"
+ if ( iAcceleratedDecoders.Count() <= 0 )
+ {
+ PRINT((_L("CTNEDecoderWrap::SetDecoderParametersL(), No suitable decoders found")))
+ User::Leave(KErrNotSupported);
+ }
+ else
+ {
+ // Select the accelerated as no ARM decoder is available
+ iUid = iAcceleratedDecoders[0];
+ iAcceleratedDecoders.Remove(0);
+ }
+ }
+
+ PRINT((_L("CTNEDecoderWrap::SetDecoderParametersL(), Out")))
+}
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::CheckDecoderInfoL
+// Checks coded info
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CTNEDecoderWrap::CheckDecoderInfoL(TUid aUid)
+{
+ CVideoDecoderInfo* decoderInfo = NULL; // Decoder info for retrieving capabilities
+ TInt status = KErrNone;
+ TBool accelerated = EFalse;
+
+ // Check decoder
+ PRINT((_L("CTNEDecoderWrap::CheckDecoderInfoL(), getting info from [0x%x]"), aUid.iUid ))
+ decoderInfo = iDevVideoPlay->VideoDecoderInfoLC( aUid );
+
+ if (!decoderInfo)
+ {
+ PRINT((_L("CTNEDecoderWrap::CheckDecoderInfoL(), getting info from [0x%x] failed[%d]"), aUid.iUid, status ))
+ User::Leave(KErrNotSupported);
+ }
+ else
+ {
+ // Check max rate for requested image format
+ TSize maxSize = decoderInfo->MaxPictureSize();
+
+ if ( (iFormat.iSize.iWidth > maxSize.iWidth) || (iFormat.iSize.iHeight > maxSize.iHeight) )
+ {
+ PRINT((_L("CTNEDecoderWrap::CheckDecoderInfoL(), Picture size is not supported")))
+ status = KErrNotSupported;
+ }
+ }
+
+ accelerated = decoderInfo->Accelerated();
+
+ // Delete codec info
+ CleanupStack::PopAndDestroy(decoderInfo);
+
+ if (status != KErrNone)
+ {
+ User::Leave(status);
+ }
+
+ return accelerated;
+}
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::InitializeL
+// Initializes decoder
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::InitializeL()
+ {
+ PRINT((_L("CTNEDecoderWrap::InitializeL(), In")))
+ TUint maxBufferSize = 0;
+ TInt status = KErrNone;
+
+ iState = ETRInitializing;
+
+ switch(iFormat.iDataType)
+ {
+ case ETRDuCodedPicture:
+ {
+ iDataUnitType = EDuCodedPicture;
+ break;
+ }
+
+ case ETRDuVideoSegment:
+ {
+ iDataUnitType = EDuVideoSegment;
+ break;
+ }
+
+ default:
+ {
+ // Should never happend. Decoder does not support uncompressed input format.
+ TRASSERT(0);
+ }
+ }
+
+ iBufferOptions.iMinNumInputBuffers = KTRDecoderMinNumberOfBuffers;
+
+ // Select decoder first
+ this->SelectDecoderL();
+
+ // Set now output format for this device
+ TRAP(status, iDevVideoPlay->SetOutputFormatL(iHwDeviceId, iUncompressedFormat));
+
+ // 3. Buffer options
+ iBufferOptions.iPreDecodeBufferSize = 0; // "0" - use default decoder value
+ iBufferOptions.iMaxPostDecodeBufferSize = 0; // No limitations
+ iBufferOptions.iPreDecoderBufferPeriod = 0;
+ iBufferOptions.iPostDecoderBufferPeriod = 0;
+
+ // Check max coded picture size for specified codec level
+ switch(iCodecLevel)
+ {
+ case KTRH263CodecLevel10:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel10;
+ break;
+ }
+
+ case KTRH263CodecLevel20:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel20;
+ break;
+ }
+
+ case KTRH263CodecLevel30:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel30;
+ break;
+ }
+
+ case KTRH263CodecLevel40:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel40;
+ break;
+ }
+
+ case KTRH263CodecLevel50:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel50;
+ break;
+ }
+
+ case KTRH263CodecLevel60:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel60;
+ break;
+ }
+
+ case KTRH263CodecLevel70:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel70;
+ break;
+ }
+
+ case KTRMPEG4CodecLevel0:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel0;
+ break;
+ }
+
+ case KTRMPEG4CodecLevel1:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel1;
+ break;
+ }
+
+ case KTRMPEG4CodecLevel2:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel2;
+ break;
+ }
+
+ case KTRMPEG4CodecLevel3:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel3;
+ break;
+ }
+
+ case KTRMPEG4CodecLevel0b:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel0b;
+ break;
+ }
+
+ case KTRMPEG4CodecLevel4a:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel4a;
+ break;
+ }
+
+ default:
+ {
+ maxBufferSize = KTRMaxBufferSizeLevel0;
+ break;
+ }
+ }
+
+ iBufferOptions.iMaxInputBufferSize = maxBufferSize;
+
+ PRINT((_L("CTNEDecoderWrap::InitializeL(), InputBufferSize[%d], NumberOfBuffers[%d]"),
+ iBufferOptions.iMaxInputBufferSize, iBufferOptions.iMinNumInputBuffers ))
+
+ iDevVideoPlay->SetBufferOptionsL(iBufferOptions);
+
+ // Initialize devVideoPlay
+ iDevVideoPlay->Initialize();
+
+ PRINT((_L("CTNEDecoderWrap::InitializeL(), Out")))
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::SelectDecoderL
+// Selects decoder
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::SelectDecoderL()
+{
+ PRINT(( _L("CTNEDecoderWrap::SelectDecoderL(), In") ))
+ TInt status = KErrNone;
+ TBool accelerated = EFalse;
+ TBool exit = EFalse;
+
+
+ if (iUid != TUid::Null())
+ {
+ TRAP( status, iHwDeviceId = iDevVideoPlay->SelectDecoderL(iUid) );
+ }
+ else
+ {
+ // Most likely an error exists, if iUid == NULL;
+ status = KErrAlreadyExists;
+ }
+
+ while ( !exit )
+ {
+ if (status == KErrNone)
+ {
+ // To get Output format list devvideoplay requires to define output format first.
+ iDevVideoPlay->SetInputFormatL(iHwDeviceId, *iCompresedFormat, iDataUnitType, EDuElementaryStream, ETrue);
+
+ // It's time to check input format support (since the plugin is loaded to the memory)
+ iUncompressedFormat.iDataFormat = EYuvRawData;
+
+ TUncompressedVideoFormat uncFormat;
+ TBool found = EFalse;
+ TInt pattern1, pattern2;
+
+ pattern1 = EYuv420Chroma1;
+ pattern2 = EYuv420Chroma2;
+
+ RArray<TUncompressedVideoFormat> supportedOutputFormats;
+ TRAP(status, iDevVideoPlay->GetOutputFormatListL( iHwDeviceId, supportedOutputFormats ));
+
+ TInt formatCount = 0;
+ if (status == KErrNone)
+ {
+ formatCount = supportedOutputFormats.Count();
+ PRINT((_L("CTNEDecoderWrap::InitializeL(), formatCount[%d]"), formatCount ))
+ }
+
+ if (formatCount <= 0)
+ {
+ supportedOutputFormats.Close();
+ status = KErrAlreadyExists;
+ PRINT((_L("CTNEDecoderWrap::InitializeL(), There are no supported output formats") ))
+ //User::Leave(KErrNotSupported);
+ }
+ else
+ {
+ // Check the most important paramers
+ for ( TInt i = 0; i < formatCount; i ++ )
+ {
+ uncFormat = supportedOutputFormats[i];
+ PRINT((_L("CTNEDecoderWrap::InitializeL(), pattern[%d]"), uncFormat.iYuvFormat.iPattern ))
+
+ if ( (uncFormat.iDataFormat == iUncompressedFormat.iDataFormat) &&
+ ( (uncFormat.iYuvFormat.iPattern == pattern1) ||
+ (uncFormat.iYuvFormat.iPattern == pattern2) ) )
+ {
+ // Assign the rest of parameters
+ iUncompressedFormat = uncFormat;
+ found = ETrue;
+ exit = ETrue;
+ supportedOutputFormats.Close();
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ supportedOutputFormats.Close();
+ PRINT((_L("CTNEDecoderWrap::InitializeL(), Supported format is not found") ))
+ //User::Leave(KErrNotSupported);
+ }
+ }
+ }
+ else
+ {
+ // Take another codec and try again
+ // Reset Uid
+ iUid = TUid::Null();
+
+ // Check codecs
+ for ( TInt i = 0; i < iCheckDecoders.Count(); i ++ )
+ {
+ TRAP( status, accelerated = CheckDecoderInfoL(iCheckDecoders[i]) );
+
+ if (status == KErrNone)
+ {
+ if (accelerated != KTRAccelerationPriorityDecoder) // The rule is defined based on study
+ {
+ // pick the first ARM decoder
+ iUid = iCheckDecoders[i];
+ iCheckDecoders.Remove(i);
+
+ // Keep the list of non-checked codecs for future use
+ // nothing to do, they are already are in the list
+ break;
+ }
+ else
+ {
+ // its a DSP based decoder add it to the accelerated decoder array
+ iAcceleratedDecoders.Insert( iAcceleratedDecoders[i], iAcceleratedDecoders.Count() );
+ }
+ }
+ }
+
+ if ( iUid == TUid::Null() )
+ {
+ // There are no ARM decoders in the system, use the accelerated ones
+ if (iAcceleratedDecoders.Count() > 0)
+ {
+ // decoders were already checked, take the first from the list
+ iUid = iAcceleratedDecoders[0];
+ iAcceleratedDecoders.Remove(0);
+ }
+ else
+ {
+ PRINT((_L("CTNEDecoderWrap::SelectDecoderL(), No suitable accelerated decoders found")))
+ User::Leave(KErrNotSupported);
+ }
+ }
+
+ status = KErrNone;
+ TRAP(status, iHwDeviceId = iDevVideoPlay->SelectDecoderL(iUid));
+ }
+ }
+
+ PRINT((_L("CTNEDecoderWrap::SelectDecoderL(), Out")))
+}
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::MdvpoInitComplete
+// Notifies for initialization complete with init status
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::MdvpoInitComplete(TInt /*aError*/)
+ {
+ iState = ETRInitialized;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::StartL
+// Starts decoding
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::StartL()
+ {
+ PRINT((_L("CTNEDecoderWrap::StartL(), In")))
+
+ // Start decoding
+ if (iFatalError == KErrNone)
+ {
+ iDevVideoPlay->Start();
+ }
+
+ if (!iInputBuffer)
+ {
+ // Get buffer from the decoder to fill
+ iInputBuffer = iDevVideoPlay->GetBufferL(iBufferOptions.iMaxInputBufferSize);
+ }
+
+ // Reset iStop
+ iStop = EFalse;
+ iState = ETRRunning;
+
+ // Reset ts monitor
+ iLastTimestamp = -1;
+
+ PRINT((_L("CTNEDecoderWrap::StartL(), Out")))
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::MdvpoNewBuffers()
+// New buffers are available
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::MdvpoNewBuffers()
+ {
+ TInt status = KErrNone;
+
+
+ if (iStop)
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoNewBuffers(), Stop was already called, nothing to do")))
+ return;
+ }
+
+ // One or more new empty input buffers are available
+ if (!iInputBuffer)
+ {
+ // Get buffer from the decoder to fill
+ TRAP(status, iInputBuffer = iDevVideoPlay->GetBufferL(iBufferOptions.iMaxInputBufferSize));
+
+ if (status != KErrNone)
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoNewBuffers(), GetBufferL status[%d]"), status))
+ iObserver->MNotifyThumbnailReady(status);
+ return;
+ }
+
+ if (!iInputBuffer)
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoNewBuffers(), There are available buffer, but decoder returned NULL")))
+ return;
+ }
+ }
+
+ if (iCodedBuffer)
+ {
+ // Send coded buffer, since the client has already done request
+ TRAP(status, this->SendBufferL(iCodedBuffer));
+
+ // Reset buffer
+ iCodedBuffer = NULL;
+
+ if (status != KErrNone)
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoNewBuffers(), Send buffer error[%d]"), status))
+ iObserver->MNotifyThumbnailReady(status);
+ return;
+ }
+ }
+
+ if ((iInputBuffer) && (iState == ETRRunning))
+ {
+ // If InputBuffer is available send
+ // more encoded packets to the decoder
+ iObserver->MSendEncodedBuffer();
+ }
+
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::WriteCodedBufferL
+// Writes coded data to decoder
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::WriteCodedBufferL(TVideoBuffer* aBuffer)
+ {
+ PRINT((_L("CTNEDecoderWrap::WriteCodedBufferL(), In")))
+ TVideoBuffer::TBufferType bufferType;
+
+ if (!aBuffer)
+ {
+ PRINT((_L("CTNEDecoderWrap::WriteCodedBufferL(), Input buffer is invalid, Leave")))
+ User::Leave(KErrArgument);
+ }
+
+ if (iFatalError != KErrNone)
+ {
+ PRINT((_L("CTNEDecoderWrap::WriteCodedBufferL(), FatalError was reported by decoder")))
+
+ // Return coded buffer
+ iObserver->MReturnCodedBuffer(aBuffer);
+ return;
+ }
+
+ TTimeIntervalMicroSeconds ts = aBuffer->TimeStamp();
+
+ if ( ts <= iLastTimestamp)
+ {
+ // Prevent propagation of the error now
+ PRINT((_L("CTNEDecoderWrap::WriteCodedBufferL(), Client sends invalid data (ts field), Leave")))
+ User::Leave(KErrArgument);
+ }
+ else
+ {
+ iLastTimestamp = ts;
+ }
+
+ if (aBuffer->BufferSize() <= 0)
+ {
+ PRINT((_L("CTNEDecoderWrap::WriteCodedBufferL(), Input data buffer is invalid (empty), Leave")))
+ User::Leave(KErrArgument);
+ }
+
+ bufferType = aBuffer->Type();
+
+ if ( ( bufferType != TVideoBuffer::EVideoH263 ) &&
+ ( bufferType != TVideoBuffer::EVideoMPEG4 ) )
+ {
+ PRINT((_L("CTNEDecoderWrap::WriteCodedBufferL(), [%d] This data type is not supported, Leave"), aBuffer->Type() ))
+ User::Leave(KErrNotSupported);
+ }
+
+ if (!iInputBuffer)
+ {
+ // Request new empty buffer
+ iInputBuffer = iDevVideoPlay->GetBufferL(iBufferOptions.iMaxInputBufferSize);
+ }
+
+ if (iInputBuffer)
+ {
+ this->SendBufferL(aBuffer);
+ }
+ else
+ {
+ iCodedBuffer = aBuffer;
+ }
+
+ PRINT((_L("CTNEDecoderWrap::WriteCodedBufferL(), Out")))
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::SendBufferL
+// Sends buffer to decoder
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::SendBufferL(TVideoBuffer* aBuffer)
+ {
+ PRINT((_L("CTNEDecoderWrap::SendBufferL(), In")))
+
+ PRINT((_L("CTNEDecoderWrap::SendBufferL(), iInputBuffer[%d], aBuffer[%d]"), iInputBuffer->iData.MaxLength(),
+ aBuffer->BufferSize() ))
+
+ if ( iInputBuffer->iData.MaxLength() < aBuffer->BufferSize() )
+ {
+ PRINT((_L("CTNEDecoderWrap::SendBufferL(), buffer length exceeds max length")))
+ User::Leave(KErrOverflow);
+ }
+
+ iInputBuffer->iData.Copy( aBuffer->Data().Ptr(), aBuffer->BufferSize() );
+ iInputBuffer->iData.SetLength( aBuffer->BufferSize() );
+
+ // Data unit presentation timestamp. Valid if EPresentationTimestamp is set in the options.
+ // If the input bitstream does not contain timestamp information, this field should be valid,
+ // otherwise pictures cannot be displayed at the correct time. If the input bitstream contains
+ // timestamp information (such as the TR syntax element of H.263 bitstreams) and valid
+ // iPresentationTimestamp is provided, the value of iPresentationTimestamp is used in playback.
+ iInputBuffer->iOptions = TVideoInputBuffer::EPresentationTimestamp;
+ iInputBuffer->iPresentationTimestamp = aBuffer->TimeStamp();
+
+ // @@ HARI AVC
+ iInputBuffer->iSequenceNumber = iInputFrameNum;
+ iInputFrameNum++;
+ iInputBuffer->iDecodingTimestamp = aBuffer->TimeStamp();
+ iInputBuffer->iPresentationTimestamp = TTimeIntervalMicroSeconds(iClockSource->Time().Int64() + 1000000);
+
+
+ /*Other data: TBC*/
+
+ // Write data to decoder
+ iDevVideoPlay->WriteCodedDataL(iInputBuffer);
+
+ // Reset InputBuffer ptr
+ iInputBuffer = NULL;
+
+ // FIXME return buffer only after it's writtent to decoder (client could write next buffer synchronously from observer call)
+ // Return buffer to the client immediately after copying
+ iObserver->MReturnCodedBuffer(aBuffer);
+
+ PRINT((_L("CTNEDecoderWrap::SendBufferL(), Out")))
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::MdvpoNewPictures
+// New decoded pictures available from decoder
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::MdvpoNewPictures()
+ {
+ TInt status = KErrNone;
+
+
+ // 1 or more decoded pictures are available
+ if (!iDecodedPicture)
+ {
+ // Get new picture
+ TRAP(status, iDecodedPicture = iDevVideoPlay->NextPictureL());
+
+ if (status != KErrNone)
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoNewPictures(), NextPicture status[%d]"), status))
+ iObserver->MNotifyThumbnailReady(status);
+ return;
+ }
+
+ if (!iDecodedPicture)
+ {
+ // Error: DevVideo notified of new buffers, but returns NULL
+ PRINT((_L("CTNEDecoderWrap::MdvpoNewPictures(), DevVideo notified of new buffers, but returns NULL")))
+ iObserver->MNotifyThumbnailReady(KErrAlreadyExists);
+ return;
+ }
+
+ // Send new picture to the client
+ iObserver->MPictureFromDecoder(iDecodedPicture);
+ }
+ else
+ {
+ // Previous picture still was not returned by the client, nothing to do.
+ // FIXME SetActive();
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::ReturnPicture
+// Returns picture
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::ReturnPicture(TVideoPicture* aPicture)
+ {
+ PRINT((_L("CTNEDecoderWrap::ReturnPicture(), In")))
+ TInt status = KErrNone;
+
+
+ iDevVideoPlay->ReturnPicture(aPicture);
+
+ // Reset decoded picture
+ iDecodedPicture = NULL;
+
+ TRAP(status, iDecodedPicture = iDevVideoPlay->NextPictureL());
+
+ if (status != KErrNone)
+ {
+ PRINT((_L("CTNEDecoderWrap::ReturnPicture(), NextPicture status[%d]"), status))
+ iObserver->MNotifyThumbnailReady(status);
+ return;
+ }
+
+ if (iDecodedPicture)
+ {
+ // Send new picture to the client
+ iObserver->MPictureFromDecoder(iDecodedPicture);
+ }
+
+ PRINT((_L("CTNEDecoderWrap::ReturnPicture(), Out")))
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::StopL
+// Stops decoding synchronously
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::StopL()
+ {
+ PRINT((_L("CTNEDecoderWrap::StopL(), In")))
+
+ if (iFatalError == KErrNone)
+ {
+ iDevVideoPlay->Stop();
+ }
+
+ iStop = ETrue;
+ iState = ETRStopped;
+
+ PRINT((_L("CTNEDecoderWrap::StopL(), Out")))
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::AsyncStopL
+// Stops decoding asynchronously
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::AsyncStopL()
+ {
+ PRINT((_L("CTNEDecoderWrap::StopL(), Async In")))
+
+ if (iFatalError == KErrNone)
+ {
+ iDevVideoPlay->InputEnd();
+ }
+
+ iStop = ETrue;
+ iState = ETRStopped;
+
+ PRINT((_L("CTNEDecoderWrap::StopL(), Async Out")))
+ }
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::GetNumInputFreeBuffers
+// returns the number of buffers that can be sent to
+// decoder
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint CTNEDecoderWrap::GetNumInputFreeBuffers()
+{
+ TUint inputFreeBuffers = iDevVideoPlay->NumFreeBuffers();
+
+ return inputFreeBuffers;
+}
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::MdvpoStreamEnd
+// Indicates when stream end is reached
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::MdvpoStreamEnd()
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoStreamEnd()")))
+ }
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::MdvpoReturnPicture
+// Returns a used input video picture back to the caller. The picture memory can be re-used or freed (only relevant to postprocessor)
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::MdvpoReturnPicture(TVideoPicture* /*aPicture*/)
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoReturnPicture()")))
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::MdvpoSupplementalInformation
+// Sends SupplementalInformation
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::MdvpoSupplementalInformation(const TDesC8& /*aData*/,
+ const TTimeIntervalMicroSeconds& /*aTimestamp*/,
+ const TPictureId& /*aPictureId*/)
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoSupplementalInformation()")))
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::MdvpoPictureLoss
+// Back channel information from the decoder, indicating a picture loss without specifying the lost picture
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::MdvpoPictureLoss()
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoPictureLoss(), report an error")))
+ iObserver->MNotifyThumbnailReady(KErrAbort);
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::MdvpoPictureLoss
+// Back channel information from the decoder, indicating the pictures that have been lost
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::MdvpoPictureLoss(const TArray< TPictureId >& /*aPictures*/)
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoPictureLoss(), pictureId: report an error")))
+ iObserver->MNotifyThumbnailReady(KErrAbort);
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::MdvpoSliceLoss
+// Reports that slice is lost
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::MdvpoSliceLoss(TUint /*aFirstMacroblock*/, TUint /*aNumMacroblocks*/,
+ const TPictureId& /*aPicture*/)
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoSliceLoss()")))
+ // This error is not considered a s fatal for decoder or application, nothing to do
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::MdvpoReferencePictureSelection
+// Back channel information from the decoder, indicating a reference picture selection request.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::MdvpoReferencePictureSelection(const TDesC8& /*aSelectionData*/)
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoReferencePictureSelection()")))
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::MdvpoTimedSnapshotComplete
+// Called when a timed snapshot request has been completed.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::MdvpoTimedSnapshotComplete(TInt /*aError*/, TPictureData* /*aPictureData*/,
+ const TTimeIntervalMicroSeconds& /*aPresentationTimestamp*/,
+ const TPictureId& /*aPictureId*/)
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoTimedSnapshotComplete()")))
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTNEDecoderWrap::MdvpoFatalError
+// Reports the fatal error to the client
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CTNEDecoderWrap::MdvpoFatalError(TInt aError)
+ {
+ PRINT((_L("CTNEDecoderWrap::MdvpoFatalError(), error[%d]"), aError))
+ iFatalError = aError;
+ iObserver->MNotifyThumbnailReady(iFatalError);
+ }
+
+
+
+
+// End of file