⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 neostreamplayer.cpp

📁 symbian下的FLV播放视频源码 可以快速便捷的播放FLV格式的视频
💻 CPP
字号:
/*
============================================================================
 Name        : NeoStreamPlayer.cpp
 Author      : 
 Version     :
 Copyright   : Your copyright notice
 Description : CNeoStreamPlayer implementation
============================================================================
*/

#include "NeoStreamPlayer.h"
#include <aknnotewrappers.h>
#include <f32file.h>
#include <coemain.h>
#include <mmf/common/mmffourcc.h>

// Bit rates in bits/sec supported by MPEG2, MPEG1 and MPEG2.5 respectively
const TInt16 KMp3BitRateTable[3][16] =
	{
		{-1,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0},
		{-1,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0},
		{-1,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0},
	};

// Sampling frequencies supported by MPEG2, MPEG1 and MPEG2.5 respectively
const TUint16 KMp3SamplingFrequencyTable[3][4] =
	{
		{22050,24000,16000,0},
		{44100,48000,32000,0},
		{11025,12000,8000,0},
	};
	
// Maximum MP3 frame size
const TInt KMp3MaxFrameSize = 1440; // 320kbit/s @ 32kHz

// The size of MP3 header, header must include bits for determining frame length
const TInt KMp3FrameHeaderSize = 5;

CNeoStreamPlayer::CNeoStreamPlayer()
{
	// No implementation required
}


CNeoStreamPlayer::~CNeoStreamPlayer()
{
	if (iAudioOutputStream)
	{
		iAudioOutputStream->Stop();
		delete iAudioOutputStream;
		iAudioOutputStream = NULL;
	}
	
	iBuffersArray.Reset();
	iBuffersArray.Close();
	
	if (iBufferLump)
	{
		User::Free(iBufferLump);
		iBufferLump = NULL;
	}
	
	if (iSrcBuf)
	{
		delete iSrcBuf;
		iSrcBuf = NULL;
	}
	
	if (iDstBuf)
	{
		delete iDstBuf;
		iDstBuf = NULL;
	}
	
	if (iMMFCodec)
	{
		delete iMMFCodec;
		iMMFCodec = NULL;
	}
}

CNeoStreamPlayer* CNeoStreamPlayer::NewLC()
{
	CNeoStreamPlayer* self = new (ELeave)CNeoStreamPlayer();
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
}

CNeoStreamPlayer* CNeoStreamPlayer::NewL()
{
	CNeoStreamPlayer* self=CNeoStreamPlayer::NewLC();
	CleanupStack::Pop(); // self;
	return self;
}

void CNeoStreamPlayer::ConstructL()
{
	iAudioOutputStream = CMdaAudioOutputStream::NewL(*this);
	iBufferLump = NULL;

	iMMFCodec = CMMFCodec::NewL(KMMFFourCCCodeMP3, KMMFFourCCCodePCM16);
	iSrcBuf = CMMFDescriptorBuffer::NewL(SRC_SIZE);
	iDstBuf = CMMFDescriptorBuffer::NewL(FRAME_SIZE * MAX_PCM_BUFFER_COUNT * 2);
	
	iOpened = EFalse;
	
	iVolume = 5;
}

void CNeoStreamPlayer::MaoscOpenComplete(TInt aError)
{
	if (aError == KErrNone)
	{
	    //CAknInformationNote* informationNote = new ( ELeave ) CAknInformationNote;
        //informationNote->ExecuteLD( _L("Open Completed!") );
        iOpened = ETrue;
//		iAudioOutputStream->SetDataTypeL(KMMFFourCCCodeMP3);
//		iAudioOutputStream->SetAudioPropertiesL(iStreamSettings.iSampleRate, iStreamSettings.iChannels);
        iAudioOutputStream->SetVolume(iAudioOutputStream->MaxVolume() * iVolume / 10);
	} else {
	    //CAknInformationNote* informationNote = new ( ELeave ) CAknInformationNote;
        //informationNote->ExecuteLD( _L("Open Failed!") );
	}
}

void CNeoStreamPlayer::MaoscBufferCopied(TInt /*aError*/, const TDesC8& aBuffer)
{
	for (TInt i = 0; i < MAX_PCM_BUFFER_COUNT ; i++)
		if (aBuffer.Ptr() == iBuffersArray[i].Ptr())
		{
			iBufferValid[i] = EFalse;
			break;
		}
}

void CNeoStreamPlayer::MaoscPlayComplete(TInt aError)
{
	if (aError == KErrUnderflow)
	{
	} else if (aError == KErrCancel)
	{
	}
}

void CNeoStreamPlayer::InitStreamPlayer(TInt32 aChannels, TInt32 aSampleRate, TInt /*aFrameSize*/)
{
	switch (aChannels)
	{
		case 1:
			iStreamSettings.iChannels = TMdaAudioDataSettings::EChannelsMono;
			break;
		case 2:
			iStreamSettings.iChannels = TMdaAudioDataSettings::EChannelsStereo;
			break;
		default:
			iStreamSettings.iChannels = TMdaAudioDataSettings::EChannelsMono;
			break;
	}
	switch (aSampleRate)
	{
		case 8000:
			iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate8000Hz;
			break;
		case 11025:
			iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate11025Hz;
			break;
		case 12000:
			iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate12000Hz;
			break;
		case 16000:
			iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate16000Hz;
			break;
		case 22050:
			iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate22050Hz;
			break;
		case 24000:
			iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate24000Hz;
			break;
		case 32000:
			iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate32000Hz;
			break;
		case 44100:
			iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate44100Hz;
			break;
		case 48000:
			iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate48000Hz;
			break;
		case 96000:
			iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate96000Hz;
			break;
		case 64000:
			iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate64000Hz;
			break;
		default:
			iStreamSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate8000Hz;
			break;
	}
	
	RArray<TInt> configParams;
	
	// Configure codec for 44.1kHz stereo output
	if (aChannels == 2)
		configParams.Append(0); // stereo to mono switch (TRUE(1) or default FALSE(0))
	else
		configParams.Append(1); // stereo to mono switch (TRUE(1) or default FALSE(0))
	configParams.Append(0); // decode left or right channel (1 left, 2 right, 0 default all)
	configParams.Append(1); // decimation factor (2, 4 or default 1)
	configParams.Append(1); // error concealment level (0 none, default 1)
	configParams.Append(16); // resolution of PCM samples (default 16 bits)
	configParams.Append(aSampleRate); //Output sampling frequency
	TUid codecId = TUid::Uid(KUidMmfCodecAudioSettings);
	TDesC8& codecData = REINTERPRET_CAST(TDesC8&, configParams);
	iMMFCodec->ConfigureL(codecId, codecData);
	configParams.Close();
	
//	iAudioOutputStream->SetPriority(80 , EMdaPriorityPreferenceTimeAndQuality);
	iOpened = EFalse;
	iAudioOutputStream->Open(&iStreamSettings);
	iBufferLumpSize = FRAME_SIZE * MAX_PCM_BUFFER_COUNT * 2 * aChannels;
	iBufferLump = (unsigned char*)(User::AllocL(iBufferLumpSize));
	iBufferSize = iBufferLumpSize / MAX_PCM_BUFFER_COUNT;
	for (TInt i = 0; i < MAX_PCM_BUFFER_COUNT; i++)
	{
		TUint8* bufPtr = iBufferLump + (iBufferSize * i);
		User::LeaveIfError(iBuffersArray.Append(TPtr8(bufPtr, 0, iBufferSize)));
		iBufferValid[i] = EFalse;
	}
}

void CNeoStreamPlayer::WriteBuffer(const signed short* aBuffer, TInt aLength)
{
	if (aLength < 0)
		return;
	TInt foundBuffer = -1;
	for (TInt i = 0; i < MAX_PCM_BUFFER_COUNT ; i++)
		if (!iBufferValid[i])
		{
			foundBuffer = i;
			break;
		}
	if (foundBuffer == -1)
		return;

	iBufferValid[foundBuffer] = ETrue;
	TPtr8& dest = iBuffersArray[foundBuffer];
	dest.Copy((const TUint8*)aBuffer, aLength);
	iAudioOutputStream->WriteL(dest);
}

void CNeoStreamPlayer::WriteBufferMP3(const unsigned char* aBuffer, TInt aLength)
{
//	if (!iOpened)
//		return;
	if (aLength < 0)
		return;

	TInt foundBuffer = -1;
	for (TInt i = 0; i < MAX_PCM_BUFFER_COUNT ; i++)
		if (!iBufferValid[i])
		{
			foundBuffer = i;
			break;
		}
	if (foundBuffer == -1)
	{
		//CEikonEnv::Static()->InfoMsg(_L("Damn"));
		return;
	}
	
	iSrcBuf->Data().Copy(aBuffer, aLength);
	TCodecProcessResult result = iMMFCodec->ProcessL(*iSrcBuf, *iDstBuf);

	iBufferValid[foundBuffer] = ETrue;
	TPtr8& dest = iBuffersArray[foundBuffer];
	dest.Copy(iDstBuf->Data());
//	dest.Copy(aBuffer, aLength);
	iAudioOutputStream->WriteL(dest);
}

void CNeoStreamPlayer::RefreshVolume()
{
	if (iAudioOutputStream)
		iAudioOutputStream->SetVolume(iAudioOutputStream->MaxVolume() * iVolume / 10);
}

void CNeoStreamPlayer::IncreaseVolume()
{
	if (iVolume < 10)
		iVolume++;
	if (iAudioOutputStream)
		iAudioOutputStream->SetVolume(iAudioOutputStream->MaxVolume() * iVolume / 10);
}

void CNeoStreamPlayer::DecreaseVolume()
{
	if (iVolume > 0)
		iVolume--;
	if (iAudioOutputStream)
		iAudioOutputStream->SetVolume(iAudioOutputStream->MaxVolume() * iVolume / 10);
}

void CNeoStreamPlayer::Stop()
{
	if (iAudioOutputStream)
		iAudioOutputStream->Stop();
}

TInt CNeoStreamPlayer::GetBytes()
{
	if (iAudioOutputStream)
		return iAudioOutputStream->GetBytes();
	return 0;
}

TInt CNeoStreamPlayer::GetMp3FrameInfo(const TUint8* aBuf, TInt aBufLen, TAudioFrameInfo& aInfo )
    {
    TInt length = 0;
    TUint temp;
    TUint lTempVal;

	// Extract header fields to aInfo and check their bit syntax
	// (including the sync word!). If the syntax is not OK the length
	// is set to zero.

	if ( aBufLen >= KMp3FrameHeaderSize )
	{
		temp = 0;
		temp = aBuf[0] << 24;
		temp |= (aBuf[1] << 16);
		temp |= (aBuf[2] << 8);
		temp |= aBuf[3];
		if ( ((temp >> 21) & 0x7FF) != 0x7FF )
			{
			return length;
			}
	
		lTempVal = (temp >> 19) & 0x03;
		switch ( lTempVal )
			{
			case 0:
				aInfo.iId = 2;  // MPEG2.5
				aInfo.iFrameSamples = 576;
				break;
			case 1:
				return length;
			case 2:
				aInfo.iId = 0;  // MPEG 2
				aInfo.iFrameSamples = 576;
				break;
			case 3:
				aInfo.iId = 1;  // MPEG 1
				aInfo.iFrameSamples = 1152;
				break;
			}
	
		lTempVal = (temp >> 17) & 0x03;
		if ( lTempVal != 1 )
			{
			return length;
			}
	
		lTempVal = (temp >> 12) & 0x0F;
		aInfo.iBitRate = KMp3BitRateTable[aInfo.iId][lTempVal] * 1000;
	
		if ( aInfo.iBitRate == 0 )
			{
			return length;
			}
	
		lTempVal = (temp >> 10) & 0x03;
		if ( lTempVal == 3 )
			{
			return length;
			}
		else
			{
			aInfo.iSamplingRate = KMp3SamplingFrequencyTable[aInfo.iId][lTempVal];
			}
	
		aInfo.iPadding = (temp >> 9) & 0x01;
	
		lTempVal = (temp >> 6) & 0x03;
		aInfo.iMode = lTempVal;
	
		if ( lTempVal == 3 )
			{
			aInfo.iChannels = 1;
			}
		else
	        {
	        aInfo.iChannels = 2;
	        }
	
	    aInfo.iSamplingRateOut = aInfo.iSamplingRate;
	    aInfo.iChannelsOut = 2; /* always set to stereo output */
	
	    aInfo.iFrameSamplesOut = aInfo.iFrameSamples;
	
		if ( aInfo.iBitRate == -1 )
			{
			// For free mode operation
			length = KMp3MaxFrameSize;
			}
	
		if ( aInfo.iSamplingRate > 0  &&  aInfo.iBitRate > 0 )
			{
			length = (144 * aInfo.iBitRate) / aInfo.iSamplingRate;
	
			if ( aInfo.iId != 1 )
				{
				length >>= 1; /*for MPEG2 and MPEG2.5 */
				}
	
			if ( aInfo.iPadding )
				{
				length++;
				}
			}
	
		aInfo.iFrameSize = length;
	}
	return length;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -