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); } }
/** 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); } }