--- a/videoeditorengine/avcedit/src/vedavceditimp.cpp Fri Jan 29 14:08:33 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1005 +0,0 @@
-/*
-* 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:
-* Implementation class for AVC editing operations.
-*
-*/
-
-
-#include <e32svr.h>
-#include <mmf/devVideo/avc.h>
-
-#include "biblin.h"
-#include "bitbuffer.h"
-#include "vld.h"
-#include "vedavceditimp.h"
-
-// Debug print macro
-#ifdef _DEBUG
-#include <e32svr.h>
-#define PRINT(x) RDebug::Print x;
-#else
-#define PRINT(x)
-#endif
-
-// An assertion macro wrapper to clean up the code a bit
-#define VPASSERT(x) __ASSERT_DEBUG(x, User::Panic(_L("CVedAVCEdit"), -10000))
-
-// ================= MEMBER FUNCTIONS =======================
-
-// Two-phased constructor
-CVedAVCEditImp* CVedAVCEditImp::NewL()
-{
- CVedAVCEditImp* self = new (ELeave) CVedAVCEditImp();
- CleanupStack::PushL(self);
- self->ConstructL();
- CleanupStack::Pop();
- return self;
-}
-
-// C++ default constructor
-CVedAVCEditImp::CVedAVCEditImp()
- {
- }
-
-// Symbian OS default constructor can leave
-void CVedAVCEditImp::ConstructL()
- {
-
- iAvcDecoder = avcdOpen();
-
- if (!iAvcDecoder)
- {
- User::Leave(KErrNoMemory);
- }
-
-#ifdef VIDEOEDITORENGINE_AVC_EDITING
- iNalLengthSize = 4;
- iOutputLevel = 10;
-#endif
-
- }
-
-// Destructor
-CVedAVCEditImp::~CVedAVCEditImp()
- {
- avcdClose(iAvcDecoder);
- }
-
-
-// ---------------------------------------------------------7
-// AVCEditParser::ProcessAVCBitStream
-// Process one input AVC frame, i.e., convert to MDF NAL unit
-// (other items were commented in a header).
-// ---------------------------------------------------------
-//
-void CVedAVCEditImp::ProcessAVCBitStreamL(TDes8& aBuf, TInt& aFrameLen, TInt aDecInfoSize, TBool aFirstFrame)
- {
-
- TUint8* dataBuffer = (TUint8*)(aBuf.Ptr());
-
- // Calculate NAL header start offset
- TInt offset = (((aFrameLen - 1) / 4) + 1) * 4; // Align at 32-bit boundrary
- TInt numNALUnits = 0;
-
- if (aFirstFrame) // There are several NAL units: decoder info and the frame
- {
- // how many bytes used for length
- iFrameLengthBytes = ( dataBuffer[4] & 0x3 ) + 1;
-
- // Index where to read configuration data
- TInt index = 5; // Skip version and length information
-
- TInt numOfSPS = dataBuffer[index] & 0x1f;
- index++;
-
- // Loop all SPS units
- for (TInt i = 0; i < numOfSPS; ++i)
- {
- TInt SPSSize = (dataBuffer[index] << 8) + dataBuffer[index + 1];
- index += 2;
-
- // Set NAL start offset
- dataBuffer[offset + 0] = TUint8(index & 0xff);
- dataBuffer[offset + 1] = TUint8((index >> 8) & 0xff);
- dataBuffer[offset + 2] = TUint8((index >> 16) & 0xff);
- dataBuffer[offset + 3] = TUint8((index >> 24) & 0xff);
-
- // Set NAL size
- dataBuffer[offset + 4] = TUint8(SPSSize & 0xff);
- dataBuffer[offset + 5] = TUint8((SPSSize >> 8) & 0xff);
- dataBuffer[offset + 6] = TUint8((SPSSize >> 16) & 0xff);
- dataBuffer[offset + 7] = TUint8((SPSSize >> 24) & 0xff);
-
- offset += 8;
- index += SPSSize;
- numNALUnits++;
- }
-
- TInt numOfPPS = dataBuffer[index];
- index++;
-
- // Loop all PPS units
- for (TInt i = 0; i < numOfPPS; ++i)
- {
- TInt PPSSize = (dataBuffer[index] << 8) + dataBuffer[index + 1];
- index += 2;
-
- // Set NAL start offset
- dataBuffer[offset + 0] = TUint8(index & 0xff);
- dataBuffer[offset + 1] = TUint8((index >> 8) & 0xff);
- dataBuffer[offset + 2] = TUint8((index >> 16) & 0xff);
- dataBuffer[offset + 3] = TUint8((index >> 24) & 0xff);
-
- // Set NAL size
- dataBuffer[offset + 4] = TUint8(PPSSize & 0xff);
- dataBuffer[offset + 5] = TUint8((PPSSize >> 8) & 0xff);
- dataBuffer[offset + 6] = TUint8((PPSSize >> 16) & 0xff);
- dataBuffer[offset + 7] = TUint8((PPSSize >> 24) & 0xff);
-
- offset += 8;
- index += PPSSize;
- numNALUnits++;
- }
-
- TInt totalFrameSize = aFrameLen;
- TInt currentProcessed = aDecInfoSize + 4; // skip DCR & length
- TUint8* frameLenPtr = const_cast<TUint8*>(aBuf.Ptr()) + aDecInfoSize;
-
- TInt frameSize = 0;
-
- // loop all slice NAL units
- while (currentProcessed < totalFrameSize)
- {
-
- // Set the NAL start offset
- dataBuffer[offset + 0] = TUint8(currentProcessed & 0xff);
- dataBuffer[offset + 1] = TUint8((currentProcessed >> 8) & 0xff);
- dataBuffer[offset + 2] = TUint8((currentProcessed >> 16) & 0xff);
- dataBuffer[offset + 3] = TUint8((currentProcessed >> 24) & 0xff);
-
- frameSize = (frameLenPtr[0] << 24) + (frameLenPtr[1] << 16) +
- (frameLenPtr[2] << 8) + frameLenPtr[3];
-
- // Set the NAL size
- dataBuffer[offset + 4] = TUint8(frameSize & 0xff);
- dataBuffer[offset + 5] = TUint8((frameSize >> 8) & 0xff);
- dataBuffer[offset + 6] = TUint8((frameSize >> 16) & 0xff);
- dataBuffer[offset + 7] = TUint8((frameSize >> 24) & 0xff);
-
- frameLenPtr += (4 + frameSize);
- currentProcessed += (4 + frameSize);
- offset += 8;
- numNALUnits++;
-
- }
-
- // Set Number of NAL units
- dataBuffer[offset + 0] = TUint8(numNALUnits & 0xff);
- dataBuffer[offset + 1] = TUint8((numNALUnits >> 8) & 0xff);
- dataBuffer[offset + 2] = TUint8((numNALUnits >> 16) & 0xff);
- dataBuffer[offset + 3] = TUint8((numNALUnits >> 24) & 0xff);
-
- aFrameLen = offset + 4;
- }
- else
- { // process just the frame
-
- TInt totalFrameSize = aFrameLen;
- TInt currentProcessed = 4; // skip length
- TUint8* frameLenPtr = const_cast<TUint8*>(aBuf.Ptr());
-
- TInt frameSize = 0;
-
- // loop all slice NAL units
- while (currentProcessed < totalFrameSize)
- {
- // Set the NAL start offset
- dataBuffer[offset + 0] = TUint8(currentProcessed & 0xff);
- dataBuffer[offset + 1] = TUint8((currentProcessed >> 8) & 0xff);
- dataBuffer[offset + 2] = TUint8((currentProcessed >> 16) & 0xff);
- dataBuffer[offset + 3] = TUint8((currentProcessed >> 24) & 0xff);
-
- frameSize = (frameLenPtr[0] << 24) + (frameLenPtr[1] << 16) +
- (frameLenPtr[2] << 8) + frameLenPtr[3];
-
- // Set the NAL size
- dataBuffer[offset + 4] = TUint8(frameSize & 0xff);
- dataBuffer[offset + 5] = TUint8((frameSize >> 8) & 0xff);
- dataBuffer[offset + 6] = TUint8((frameSize >> 16) & 0xff);
- dataBuffer[offset + 7] = TUint8((frameSize >> 24) & 0xff);
-
- frameLenPtr += (4 + frameSize);
- currentProcessed += (4 + frameSize);
- offset += 8;
- numNALUnits++;
- }
-
- // Number of NAL units
- dataBuffer[offset + 0] = TUint8(numNALUnits & 0xff);
- dataBuffer[offset + 1] = TUint8((numNALUnits >> 8) & 0xff);
- dataBuffer[offset + 2] = TUint8((numNALUnits >> 16) & 0xff);
- dataBuffer[offset + 3] = TUint8((numNALUnits >> 24) & 0xff);
-
- aFrameLen = offset + 4;
- }
- //iDataLength = iCurrentFrameLength;
- }
-
-// ---------------------------------------------------------
-// CVedAVCEditImp::GetMaxAVCFrameBuffering
-// Calculate maximum amount of buffered AVC frames
-// (other items were commented in a header).
-// ---------------------------------------------------------
-//
-TInt CVedAVCEditImp::GetMaxAVCFrameBuffering(TInt aLevel, TSize aResolution)
- {
-
- TReal maxDPB = 0.0;
- switch (aLevel)
- {
- case 11:
- maxDPB = 337.5;
- break;
-
- case 12:
- maxDPB = 891.0;
- break;
-
- case 10:
- case 101:
- default:
- maxDPB = 148.5;
- break;
- }
-
- TInt mbWidth = aResolution.iWidth / 16;
- TInt mbHeight = aResolution.iHeight / 16;
-
- TInt maxDPBSize = TInt( ( TReal(1024.0) * maxDPB ) / ( TReal(mbWidth*mbHeight*384.0) ) );
-
- maxDPBSize = min(maxDPBSize, 16);
-
- return maxDPBSize;
- }
-
-// ---------------------------------------------------------
-// CVedAVCEditImp::GetLevel
-// Get input bitstream level from SPS
-// ---------------------------------------------------------
-//
-TInt CVedAVCEditImp::GetLevel(TDesC8& aBuf, TInt& aLevel)
- {
- TUint8* buffer = (TUint8*)(aBuf.Ptr());
-
- TInt index = 5; // Skip version and length information
-
-#ifdef _DEBUG
- TInt numOfSPS = buffer[index] & 0x1f;
- VPASSERT(numOfSPS == 1);
-#endif
-
- index++;
-
- TUint SPSSize = (buffer[index] << 8) + buffer[index + 1];
- index += 2;
-
- TInt error = avcdParseLevel(iAvcDecoder, (void*)&buffer[index], &SPSSize, aLevel);
-
- if (error != KErrNone)
- return error;
-
- return KErrNone;
- }
-
-
-// ---------------------------------------------------------
-// CVedAVCEditImp::GetResolution
-// Get input bitstream resolution from SPS
-// ---------------------------------------------------------
-//
-TInt CVedAVCEditImp::GetResolution(TDesC8& aBuf, TSize& aResolution)
-{
-
- TUint8* buffer = (TUint8*)(aBuf.Ptr());
-
- TInt index = 5; // Skip version and length information
-
-#ifdef _DEBUG
- TInt numOfSPS = buffer[index] & 0x1f;
- VPASSERT(numOfSPS == 1);
-#endif
-
- index++;
-
- TUint SPSSize = (buffer[index] << 8) + buffer[index + 1];
- index += 2;
-
- TInt error = avcdParseResolution(iAvcDecoder, (void*)&buffer[index], &SPSSize,
- aResolution.iWidth, aResolution.iHeight);
-
- if (error != KErrNone)
- return error;
-
- return KErrNone;
-}
-
-
-
-#ifdef VIDEOEDITORENGINE_AVC_EDITING
-// ---------------------------------------------------------
-// AVCEditParser::SaveAVCDecoderConfigurationRecordL
-// Saves SPS/PPS Nal units from AVCDecoderConfigurationRecord
-// (other items were commented in a header).
-// ---------------------------------------------------------
-//
-void CVedAVCEditImp::SaveAVCDecoderConfigurationRecordL(TDes8& aBuf, TBool aFromEncoder)
- {
-
- TUint8* buffer = (TUint8*)(aBuf.Ptr());
-
- TInt index = 5; // Skip version and length information
-
- TInt numOfSPS = buffer[index] & 0x1f;
- index++;
-
- // Loop all SPS units
- for (TInt i = 0; i < numOfSPS; ++i)
- {
- TUint SPSSize = (buffer[index] << 8) + buffer[index + 1];
- index += 2;
-
- // feed NAL for saving to ParseParameterSet()
- User::LeaveIfError( ParseParameterSet( (void*)&buffer[index], &SPSSize, aFromEncoder ) );
- index += SPSSize;
-
- }
-
- TInt numOfPPS = buffer[index];
- index++;
-
- // Loop all PPS units
- for (TInt i = 0; i < numOfPPS; ++i)
- {
- TUint PPSSize = (buffer[index] << 8) + buffer[index + 1];
- index += 2;
-
- // feed NAL for saving to ParseParameterSet()
- User::LeaveIfError( ParseParameterSet( (void*)&buffer[index], &PPSSize, aFromEncoder ) );
- index += PPSSize;
-
- }
-
- }
-
-// ---------------------------------------------------------
-// CVedAVCEditImp::ConvertAVCHeader
-// Convert AVC specific decoder config info to
-// AVCDecoderConfigurationRecord -format
-// (other items were commented in a header).
-// ---------------------------------------------------------
-//
-void CVedAVCEditImp::ConvertAVCHeaderL( TDesC8& aSrcBuf, TDes8& aDstBuf )
- {
-
- TUint8* inputPtr = (TUint8*)(aSrcBuf.Ptr());
- TUint8* outputPtr = (TUint8*)(aDstBuf.Ptr());
- TUint8* spsPtr;
- TUint8* ppsPtr;
-
- TUint numSPS = 0;
- TUint numPPS = 0;
-
- TUint totalSPSLength = 0;
- TUint totalPPSLength = 0;
-
- TUint headerLength = aSrcBuf.Length();
- TUint endIndex = headerLength;
-
- TInt nalType = 0;
- TUint nalLength;
- TUint nalIndex;
- TUint nalOffset;
-
- // Allocate memory for the temporary buffers
- HBufC8* temp1 = (HBufC8*) HBufC8::NewLC(1000);
- HBufC8* temp2 = (HBufC8*) HBufC8::NewLC(5000);
-
- spsPtr = const_cast<TUint8*>( temp1->Des().Ptr() );
- ppsPtr = const_cast<TUint8*>( temp2->Des().Ptr() );
-
- TUint numNalUnits = inputPtr[endIndex-4] + (inputPtr[endIndex-3]<<8) + (inputPtr[endIndex-2]<<16) + (inputPtr[endIndex-1]<<24);
-
- // Move endIndex to point to the first NAL unit's offset information
- endIndex = headerLength - numNalUnits*8 - 4;
-
- nalIndex = 0;
-
- TUint8* copyPtr = inputPtr;
-
- while (nalIndex < numNalUnits)
- {
- nalIndex++;
-
- TInt tmp1 = inputPtr[endIndex++];
- TInt tmp2 = inputPtr[endIndex++]<<8;
- TInt tmp3 = inputPtr[endIndex++]<<16;
- TInt tmp4 = inputPtr[endIndex++]<<24;
-
- nalOffset = tmp1 + tmp2 + tmp3 + tmp4;
-
- tmp1 = inputPtr[endIndex++];
- tmp2 = inputPtr[endIndex++]<<8;
- tmp3 = inputPtr[endIndex++]<<16;
- tmp4 = inputPtr[endIndex++]<<24;
-
- nalLength = tmp1 + tmp2 + tmp3 + tmp4;
-
- nalType = inputPtr[nalOffset] & 0x1F;
-
- if(nalType == 7)
- {
- numSPS++;
-
- // First store the SPS unit length with two bytes
- spsPtr[totalSPSLength] = (nalLength >> 8) & 0xFF;
- spsPtr[totalSPSLength+1] = nalLength & 0xFF;
-
- // Copy the SPS unit to the buffer
- Mem::Copy(&spsPtr[totalSPSLength+2], copyPtr , nalLength);
-
- totalSPSLength += nalLength + 2; // Two more for the size
- }
- else if(nalType == 8)
- {
- numPPS++;
-
- // First store the SPS unit length with two bytes
- ppsPtr[totalPPSLength] = (nalLength >> 8) & 0xFF;
- ppsPtr[totalPPSLength+1] = nalLength & 0xFF;
-
- // Copy the SPS unit to the buffer
- Mem::Copy(&ppsPtr[totalPPSLength+2], copyPtr , nalLength);
-
- totalPPSLength += nalLength + 2; // Two more for the size
- }
- else
- {
- // [KW]: Check later if this is an error!!!
- }
-
- copyPtr += nalLength;
- }
-
- // When the header has been parsed, form the AVCDecoderConfigurationRecord
- outputPtr[0] = 0x01; // configurationVersion
- outputPtr[1] = 0x42; // Profile indicator
- // Profile compatibility, i.e. all 4 constrain set flags + reserved 4 zero bits
- outputPtr[2] = 0x80; // Bitstream obeys all baseline constraints
- if ( iOutputLevel == 101 )
- {
- // For level 1b, the 4th bit shall be == 1, otherwise it must be zero
- outputPtr[2] |= 0x10;
- }
- else
- {
- outputPtr[2] &= 0xEF;
- }
-
- outputPtr[3] = (iOutputLevel == 101) ? 11 : iOutputLevel; // level
-
- outputPtr[4] = 0x03; // lengthSizeMinusOne
- outputPtr[4] |= 0x0FC; // 6 reserved bits (all 1)
-
- outputPtr[5] = numSPS;
- outputPtr[5] |= 0xE0; // 3 reserved bits (all 1)
-
- TInt len = 6;
-
- // Copy the SPS unit(s) to the buffer
- Mem::Copy(&outputPtr[6], spsPtr , totalSPSLength);
-
- len += totalSPSLength;
-
- outputPtr[6+totalSPSLength] = numPPS;
-
- len += 1;
-
- // Copy the PPS unit(s) to the buffer
- Mem::Copy(&outputPtr[6+totalSPSLength+1], ppsPtr , totalPPSLength);
-
- len += totalPPSLength;
-
- aDstBuf.SetLength(len);
-
- CleanupStack::Pop(2);
-
- // Free the temporary buffers
- delete temp1;
- delete temp2;
-}
-
-
-// ---------------------------------------------------------
-// CVedAVCEditImp::ParseOneNAL
-// Saves one SPS/PPS NAL unit for later use
-// ---------------------------------------------------------
-//
-TInt CVedAVCEditImp::ParseParameterSet(void *aNalUnitData, TUint* aNalUnitLength, TBool aFromEncoder)
- {
- TInt retCode;
-
- // Pass the information about the frame origin to the decoder
- FrameIsFromEncoder(iAvcDecoder, aFromEncoder);
- // Just call the decoder's parser function
- retCode = avcdParseParameterSet(iAvcDecoder, aNalUnitData, aNalUnitLength);
-
- return retCode;
- }
-
-TInt CVedAVCEditImp::ParseOneNAL(void *aNalUnitData, TUint* aNalUnitLength, TBool aFromEncoder)
- {
- TInt retCode;
-
- // Pass the information about the frame origin to the decoder
- FrameIsFromEncoder(iAvcDecoder, aFromEncoder);
- // Just call the decoder's parser function
- retCode = avcdParseOneNal(iAvcDecoder, aNalUnitData, aNalUnitLength);
-
- return retCode;
- }
-
-// ---------------------------------------------------------
-// CVedAVCEditImp::ParseFrame
-// Update slice header information
-// ---------------------------------------------------------
-//
-TInt CVedAVCEditImp::ParseFrame(HBufC8*& aBuf, TBool aContainsDCR, TBool aFromEncoder)
-{
- TUint nalSize;
- TUint nalOrigSize = 0;
- TUint nalLengthSize = 0;
-// TInt nalType;
-// TInt nalRefIdc;
- TInt skip = 0;
- TUint bufferLength = aBuf->Length();
- TPtr8 bufferPtr(aBuf->Des());
- TUint8* srcPtr = (TUint8*)(bufferPtr.Ptr());
-
- TInt error;
- HBufC8* temp1 = 0;
- TRAP( error, temp1 = (HBufC8*) HBufC8::NewL(10) );
-
- if (error != KErrNone)
- return error;
-
- TPtr8 tempPtr(temp1->Des());
-// TUint tmpLength1;
-// TUint tmpLength2;
- TUint8* tempData1;
-
- tempPtr.Append(5);
-
- // Jump over the AVC decoder information if it's included
- if(aContainsDCR)
- {
- // skip 4 bytes for
- // configVersion, profile, profile compatibility and Level
- skip += 4;
-
- // skip 1 byte for lengthSizeMinusOne
- skip += 1;
-
- // skip 1 byte for number of sequence parameter sets
- TInt numOfSSP = 0x1F & srcPtr[skip];
- skip += 1;
-
- for (TInt i = 0; i < numOfSSP; i++)
- {
- TInt sspSize = srcPtr[skip]*256 + srcPtr[skip+1];
- skip += 2;
- skip += sspSize;
- }
-
- TInt numOfPSP = srcPtr[skip];
- skip += 1;
-
- for (TInt i = 0; i < numOfPSP; i++)
- {
- TInt pspSize = srcPtr[skip]*256 + srcPtr[skip+1];
- skip += 2;
- skip += pspSize;
- }
- }
-
- while (skip < bufferLength)
- {
-
- TInt retVal = 0;
-
- nalLengthSize = iNalLengthSize;
- switch (nalLengthSize)
- {
- case 1:
- nalOrigSize = nalSize = srcPtr[skip];
- skip += 1;
- break;
- case 2:
- nalOrigSize = nalSize = (srcPtr[skip] << 8) + srcPtr[skip+1];
- skip += 2;
- break;
- case 4:
- nalOrigSize = nalSize = (srcPtr[skip] << 24) + (srcPtr[skip+1] << 16) +
- (srcPtr[skip+2] << 8) + srcPtr[skip+3];
-
- skip += 4;
- break;
- }
-
-// nalType = srcPtr[skip] & 0x1F;
-// nalRefIdc = srcPtr[skip] & 0x60;
-
- // [KW]: Alloc memory here instead of sequence.cpp
- tempData1 = (TUint8*) User::Alloc(nalOrigSize+100);
-
- if (tempData1 == 0)
- {
- User::Free(temp1);
- return KErrNoMemory;
- }
-
- Mem::Copy(tempData1, &srcPtr[skip], nalOrigSize*sizeof(TUint8));
-
- Mem::FillZ(&tempData1[nalOrigSize], 100*sizeof(TUint8));
-
- // Call ParseOneNaL function
- retVal = ParseOneNAL(tempData1, &nalSize, aFromEncoder);
-
- if (retVal != KErrNone)
- {
- User::Free(tempData1);
- User::Free(temp1);
- return retVal;
- }
-
- // Copy data back to the srcPtr
- Mem::Copy(&srcPtr[skip],tempData1,nalOrigSize*sizeof(TUint8));
-
-// tmpLength1 = aBuf->Length();
- if(nalSize > nalOrigSize)
- {
- TUint diff = nalSize - nalOrigSize;
-
- for (TInt i=0; i<diff; i++)
- {
- tempPtr.Delete(0,1);
- tempPtr.Append(tempData1[nalOrigSize+i]);
-// tmpLength2 = tempPtr.Length();
-
- // Insert byte(s) into the buffer
- if((bufferPtr.Length() + 1) > bufferPtr.MaxLength())
- {
- // extend buffer size
- TUint newSize = bufferPtr.Length() + 1;
-
- // round up to the next full kilobyte
- newSize = (newSize + 1023) & (~1023);
- TRAP(error, (aBuf = aBuf->ReAllocL(newSize)) );
-
- if (error != KErrNone)
- {
- User::Free(tempData1);
- User::Free(temp1);
- return error;
- }
-
- bufferPtr.Set(aBuf->Des());
- }
-
- bufferPtr.Insert(skip+nalOrigSize+i,tempPtr);
-// tmpLength1 = aBuf->Length();
- }
- bufferLength += diff;
- }
- else if(nalSize < nalOrigSize)
- {
- TUint diff = nalOrigSize - nalSize;
-
- // Delete diff bytes from the buffer
- bufferPtr.Delete(skip+nalOrigSize-diff,diff);
-
- bufferLength -= diff;
- }
-
- // Update the NAL unit's size information in the buffer
- srcPtr[skip-4] = TUint8((nalSize >> 24) & 0xff);
- srcPtr[skip-3] = TUint8((nalSize >> 16) & 0xff);
- srcPtr[skip-2] = TUint8((nalSize >> 8) & 0xff);
- srcPtr[skip-1] = TUint8(nalSize & 0xff);
-
- // Free the temporary data
- User::Free(tempData1);
-
- skip += nalSize;
- }
-
- User::Free(temp1);
-
- return KErrNone;
-}
-
-// ---------------------------------------------------------
-// CVedAVCEditImp::ConstructAVCDecoderConfigurationRecordL
-// Constructs AVCDecoderConfigurationRecord for output
-// ---------------------------------------------------------
-//
-void CVedAVCEditImp::ConstructAVCDecoderConfigurationRecordL( TDes8& aDstBuf )
- {
-
- TUint8* outputPtr = (TUint8*)(aDstBuf.Ptr());
- TUint8* spsPtr;
- TUint8* ppsPtr;
-
- TUint numSPS = 0;
- TUint numPPS = 0;
-
- TUint totalSPSLength = 0;
- TUint totalPPSLength = 0;
-
- TInt i;
- TUint spsLength;
- TUint ppsLength;
- TInt len = 6;
- TUint8* copyPtr;
-
-
- // Allocate memory for the temporary buffers
- HBufC8* temp1 = (HBufC8*) HBufC8::NewLC(1000);
- HBufC8* temp2 = (HBufC8*) HBufC8::NewLC(5000);
-
- spsPtr = const_cast<TUint8*>( temp1->Des().Ptr() );
- ppsPtr = const_cast<TUint8*>( temp2->Des().Ptr() );
-
- numSPS = ReturnNumSPS(iAvcDecoder);
- numPPS = ReturnNumPPS(iAvcDecoder);
-
- for (i=0; i<numSPS; i++)
- {
- copyPtr = ReturnSPSSet(iAvcDecoder,i,&spsLength);
-
- // First store the SPS unit length with two bytes
- spsPtr[totalSPSLength] = (spsLength >> 8) & 0xFF;
- spsPtr[totalSPSLength+1] = spsLength & 0xFF;
-
- // Copy the SPS unit to the buffer
- Mem::Copy(&spsPtr[totalSPSLength+2], copyPtr , spsLength);
-
- totalSPSLength += spsLength + 2; // Two more for the size
- }
-
-
- for (i=0; i<numPPS; i++)
- {
- copyPtr = ReturnPPSSet(iAvcDecoder,i,&ppsLength);
-
- // First store the PPS unit length with two bytes
- ppsPtr[totalPPSLength] = (ppsLength >> 8) & 0xFF;
- ppsPtr[totalPPSLength+1] = ppsLength & 0xFF;
-
- // Copy the PPS unit to the buffer
- Mem::Copy(&ppsPtr[totalPPSLength+2], copyPtr , ppsLength);
-
- totalPPSLength += ppsLength + 2; // Two more for the size
- }
-
-
-
- // When the header has been parsed, form the AVCDecoderConfigurationRecord
- outputPtr[0] = 0x01;
- outputPtr[1] = 0x42; // Profile indicator, baseline profile
-
- // Profile compatibility, i.e. all 4 constrain set flags + reserved 4 zero bits
- outputPtr[2] = 0x80; // Bitstream obeys all baseline constraints
- if ( iOutputLevel == 101 )
- {
- // For level 1b, the 4th bit shall be == 1, otherwise it must be zero
- outputPtr[2] |= 0x10;
- }
- else
- {
- outputPtr[2] &= 0xEF;
- }
-
- outputPtr[3] = (iOutputLevel == 101) ? 11 : iOutputLevel; // level
- outputPtr[4] = 0x03; // lengthSizeMinusOne
- outputPtr[5] = numSPS;
-
-
- // Copy the SPS unit(s) to the buffer
- Mem::Copy(&outputPtr[6], spsPtr , totalSPSLength);
-
- len += totalSPSLength;
-
- outputPtr[6+totalSPSLength] = numPPS;
-
- len += 1;
-
- // Copy the PPS unit(s) to the buffer
- Mem::Copy(&outputPtr[6+totalSPSLength+1], ppsPtr , totalPPSLength);
-
- len += totalPPSLength;
-
- aDstBuf.SetLength(len);
-
- CleanupStack::Pop(2);
- // Free the temporary buffers
- delete temp1;
- delete temp2;
- }
-
-
-// ---------------------------------------------------------
-// CVedAVCEditImp::EncodeUntilIDR
-// Returns whether frames have to be encoded until next IDR frame
-// ---------------------------------------------------------
-//
-TBool CVedAVCEditImp::EncodeUntilIDR()
-{
- if (iAvcDecoder)
- {
- return (ReturnEncodeUntilIDR(iAvcDecoder));
- }
- else
- {
- return EFalse;
- }
-}
-
-
-// ---------------------------------------------------------
-// CVedAVCEditImp::IsNALUnitIDR
-// Returns whether passed frame is an IDR frame
-// ---------------------------------------------------------
-//
-TBool CVedAVCEditImp::IsNALUnitIDR( TDes8& aNalBuf )
-{
- TUint8* bufferPtr = (TUint8*)(aNalBuf.Ptr());
-
- // skip 4 bytes of length information
- if((bufferPtr[4] & 0x1F) == 5)
- return ETrue;
- else
- return EFalse;
-}
-
-// ---------------------------------------------------------
-// CVedAVCEditImp::StoreCurrentPPSId
-// Stores the PPS id of passed frame for later use
-// ---------------------------------------------------------
-//
-void CVedAVCEditImp::StoreCurrentPPSId( TDes8& aNalBuf )
-{
- TUint8* bufferPtr = (TUint8*)(aNalBuf.Ptr());
- TUint bufferLength = aNalBuf.Length();
-
- switch (iNalLengthSize)
- {
- case 1:
- bufferLength = bufferPtr[0];
- bufferPtr += 1;
- break;
- case 2:
- bufferLength = (bufferPtr[0] << 8) + bufferPtr[1];
- bufferPtr += 2;
- break;
- case 4:
- bufferLength = (bufferPtr[0] << 24) + (bufferPtr[1] << 16) +
- (bufferPtr[2] << 8) + bufferPtr[3];
-
- bufferPtr += 4;
- break;
- }
- avcdStoreCurrentPPSId(iAvcDecoder, bufferPtr, bufferLength);
-}
-
-// ---------------------------------------------------------
-// CVedAVCEditImp::GenerateNotCodedFrame
-// Generates a not coded (empty) frame
-// ---------------------------------------------------------
-//
-TInt CVedAVCEditImp::GenerateNotCodedFrame( TDes8& aNalBuf, TUint aFrameNumber )
-{
- TUint8* bufferPtr = (TUint8*)(aNalBuf.Ptr());
- TUint bufferLength = aNalBuf.Length();
- TInt frameLength = 0;
-
- frameLength = avcdGenerateNotCodedFrame(iAvcDecoder, bufferPtr, bufferLength, aFrameNumber);
-
- if(frameLength > 0)
- {
- TInt i;
-
- // Make room for iNalLengthSize bytes of length information to the start
- for (i=frameLength-1; i>=0; i--)
- {
- bufferPtr[i+iNalLengthSize] = bufferPtr[i];
- }
-
- // Add the NAL size information to the buffer
- switch (iNalLengthSize)
- {
- case 1:
- bufferPtr[0] = TUint8(frameLength & 0xff);
- frameLength++;
- break;
- case 2:
- bufferPtr[0] = TUint8((frameLength >> 8) & 0xff);
- bufferPtr[1] = TUint8(frameLength & 0xff);
- frameLength += 2;
- break;
- case 4:
- bufferPtr[0] = TUint8((frameLength >> 24) & 0xff);
- bufferPtr[1] = TUint8((frameLength >> 16) & 0xff);
- bufferPtr[2] = TUint8((frameLength >> 8) & 0xff);
- bufferPtr[3] = TUint8(frameLength & 0xff);
- frameLength += 4;
- break;
- }
-
- return frameLength;
- }
- else
- return 0;
-}
-
-// ---------------------------------------------------------
-// CVedAVCEditImp::ModifyFrameNumber
-// Modifies the frame number of input NAL unit
-// ---------------------------------------------------------
-//
-void CVedAVCEditImp::ModifyFrameNumber( TDes8& aNalBuf, TUint aFrameNumber )
-{
- TUint8* bufferPtr = (TUint8*)(aNalBuf.Ptr());
- TUint bufferLength = aNalBuf.Length();
-
- switch (iNalLengthSize)
- {
- case 1:
- bufferLength = bufferPtr[0];
- bufferPtr += 1;
- break;
- case 2:
- bufferLength = (bufferPtr[0] << 8) + bufferPtr[1];
- bufferPtr += 2;
- break;
- case 4:
- bufferLength = (bufferPtr[0] << 24) + (bufferPtr[1] << 16) +
- (bufferPtr[2] << 8) + bufferPtr[3];
-
- bufferPtr += 4;
- break;
- }
-
- if (bufferPtr[0]==0x01 && bufferPtr[1]==0x42)
- return;
-
- avcdModifyFrameNumber(iAvcDecoder, bufferPtr, bufferLength, aFrameNumber);
-}
-
-#endif
-
-// End of file
-
-