void CPlayAudioFile::ReadNextBuffer(CMMFBuffer& aHwDataBuffer)
	{
	TBool finished = EFalse;
	TInt length = iSourceFile->Size();
	if (iSourceFilePos < length)
		{
		TInt size = length - iSourceFilePos;
		CMMFDataBuffer* dataBuffer = static_cast<CMMFDataBuffer*>(&aHwDataBuffer);
		if (size > dataBuffer->Data().MaxLength())
			{
			size = dataBuffer->Data().MaxLength();
			}
		else
			{
			dataBuffer->SetLastBuffer(ETrue);
			finished = ETrue;
			}
		dataBuffer->Data().SetLength(size);
		Mem::Copy((TAny*)dataBuffer->Data().Ptr(), (TAny*)iSourceFile->Mid(iSourceFilePos).Ptr(), size);
		iSourceFilePos += size;
		}
	iHwDevice->ThisHwBufferFilled(aHwDataBuffer);
	if (finished)
		{
		SetState(EHwDeviceAllowToComplete);
		}
	}
예제 #2
0
/**
Fills the buffer with audio/Video data and informs the observer
@param aBuffer
*/
void CAviReader::BufferFilledL(CMMFBuffer* aBuffer)
{
    if (!aBuffer)
    {
        User::Leave(KErrArgument);
    }
    if (aBuffer == iVideoBuffer)
    {
        //callback for video read when the file is not interleaved(No REC lists)
        iBufferFromDevVideo->iData.Copy(iVideoBuffer->Data());
        iObserver.VideoBufferFilled(iBufferFromDevVideo);
    }
    else if (aBuffer == iAudioBuffer)
    {
        //callback for audio read when the file is not interleaved(No REC lists)
        CMMFDataBuffer* bufferFromSink = static_cast<CMMFDataBuffer*>(iBufferFromDevSound);

        TInt sinkBufLen = bufferFromSink->Data().MaxSize();
        TInt audBufLen = iAudioBuffer->Data().Length();

        if (sinkBufLen < audBufLen)
        {
            bufferFromSink->Data().Copy(iAudioBuffer->Data().Ptr(), sinkBufLen);
            CMMFDescriptorBuffer* tempBuffer = CMMFDescriptorBuffer::NewL(audBufLen - sinkBufLen);
            tempBuffer->Data().Copy(iAudioBuffer->Data().Mid(sinkBufLen));
            delete iAudioBuffer;
            iAudioBuffer = tempBuffer;
        }
        else
        {
            // DEF113319 - call SetLastBuffer when sending last audio chunk
            TInt position = 0;
            position = (iMainHeader.iFlags == KAVIF_ISINTERLEAVED) ? iSourcePos : iAudioPos;
            if(!IsAudioDataAvailableL(position))
            {
                bufferFromSink->SetLastBuffer(ETrue);
                SetMediaEOS(KUidMediaTypeAudio);
            }

            bufferFromSink->Data().Copy(iAudioBuffer->Data());
            delete iAudioBuffer;
            iAudioBuffer = NULL;
        }
        iObserver.AudioBufferFilled();
    }
    else if (aBuffer == iSourceBuffer)//callback for REC list
    {
        //callback for REC list read. We need to extract video and audio chunks from the sourcebuffer
        TUint8* rawform = &(iSourceBuffer->Data()[0]);
        TInt desPos = 0; //position in descriptor

        //Now we should be pointing to audio or video chunks
        TInt bufLen = iSourceBuffer->Data().Length();
        if(bufLen < 4)
        {
            User::Leave(KErrCorrupt);
        }
        rawform += 4; //skip the fourcc of REC
        desPos += 4; //byte count corresponding to where rawform points to

        if (bufLen - desPos < 8)
        {
            //if the buffer is not long enough to accomodate - chunk id and size leave
            User::Leave(KErrCorrupt);
        }

        for (TUint8 i=0; i < iMainHeader.iStreams; i++)//we expect only 2 streams at the moment
        {
            if (desPos == bufLen) //caution check for the necessity of the block
            {
                //Sometimes we only have one stream in this list. No more data to read
                break;
            }

            if (bufLen - desPos < 8 && i== 1)
            {
                //if the buffer is not long enough to accomodate - chunk id and size leave
                break;
            }

            TUint32 dwChunkId = Read32(rawform);
            rawform += 4; //Skip chunkId
            desPos += 4;
            TBool bAudioId = EFalse;
            TBool bVideoId = EFalse;
            switch (dwChunkId)	//identify chunk
            {
            case KRiffChunkName00db:
            case KRiffChunkName00dc:
            case KRiffChunkName01db:
            case KRiffChunkName01dc:
                bVideoId = ETrue;
                break;
            case KRiffChunkName00wb:
            case KRiffChunkName01wb:
                bAudioId = ETrue;
                break;
            default:
                User::Leave(KErrCorrupt);
            }

            if (!bAudioId && !bVideoId)
            {
                //we are supposed to get audio or video stream here. if anything else, we return KErrCorrupt
                User::Leave(KErrCorrupt);
            }
            TUint32 dwChunkSz = Read32(rawform);
            if (dwChunkSz > bufLen - desPos)
            {
                User::Leave(KErrCorrupt); //caution - check
            }
            rawform += 4; //Skip chunkSize
            desPos += 4;
            TPtr8 temp = iSourceBuffer->Data().MidTPtr(desPos, dwChunkSz);
            if (bVideoId)// video
            {
                if (iVideoRequestMade)
                {
                    //if video request is already made we can copy the data directly into the devvideo buffer
                    //instead of iVideoBuffer
                    iBufferFromDevVideo->iData.Copy(temp);
                }
                else
                {
                    //DevVideo request is not made. So copy the data into video buffer
                    delete iVideoBuffer;
                    iVideoBuffer = NULL;
                    iVideoBuffer = CMMFDescriptorBuffer::NewL(dwChunkSz);
                    iVideoBuffer->Data().Copy(temp);
                }
            }
            else if (bAudioId)//audio
            {
                if (iAudioRequestMade)
                {
                    //if audio request is already made, copy the data into devsound buffer
                    CMMFDataBuffer* bufferFromSink = static_cast<CMMFDataBuffer*>(iBufferFromDevSound);
                    bufferFromSink->Data().Copy(temp);
                }
                else
                {
                    //DevSound request is not made. copy the audio chunk into audio buffer
                    delete iAudioBuffer;
                    iAudioBuffer = NULL;
                    iAudioBuffer = CMMFDescriptorBuffer::NewL(dwChunkSz);
                    iAudioBuffer->Data().Copy(temp);
                }
            }
            rawform	+= dwChunkSz;//Skip video/audio chunk
            desPos += dwChunkSz;
        }
        iReadCompleted = ETrue;//REC list is read
        // we send the bufferfilled callbacks after both audio and video requests are made.
        ReadComplete();
    }
    else
    {
        User::Leave(KErrCorrupt);
    }
}