diff --git a/engines/2way/src/pv_2way_sdkinfo.h b/engines/2way/src/pv_2way_sdkinfo.h index 80b471156..687f6aa18 100644 --- a/engines/2way/src/pv_2way_sdkinfo.h +++ b/engines/2way/src/pv_2way_sdkinfo.h @@ -21,7 +21,7 @@ // This header file is automatically generated at build-time // *** OFFICIAL RELEASE INFO -- Will not auto update -#define PV2WAY_ENGINE_SDKINFO_LABEL "1510718" +#define PV2WAY_ENGINE_SDKINFO_LABEL "1511188" #define PV2WAY_ENGINE_SDKINFO_DATE 0x20100622 #endif //PV_2WAY_SDKINFO_H_INCLUDED diff --git a/engines/author/src/pv_author_sdkinfo.h b/engines/author/src/pv_author_sdkinfo.h index fff161853..556c0506e 100644 --- a/engines/author/src/pv_author_sdkinfo.h +++ b/engines/author/src/pv_author_sdkinfo.h @@ -21,7 +21,7 @@ // This header file is automatically generated at build-time // *** OFFICIAL RELEASE INFO -- Will not auto update -#define PVAUTHOR_ENGINE_SDKINFO_LABEL "1510718" +#define PVAUTHOR_ENGINE_SDKINFO_LABEL "1511188" #define PVAUTHOR_ENGINE_SDKINFO_DATE 0x20100622 #endif //PV_AUTHOR_SDKINFO_H_INCLUDED diff --git a/engines/player/src/pv_player_sdkinfo.h b/engines/player/src/pv_player_sdkinfo.h index 8aa0c1092..b2e90d763 100644 --- a/engines/player/src/pv_player_sdkinfo.h +++ b/engines/player/src/pv_player_sdkinfo.h @@ -21,7 +21,7 @@ // This header file is automatically generated at build-time // *** OFFICIAL RELEASE INFO -- Will not auto update -#define PVPLAYER_ENGINE_SDKINFO_LABEL "1510718" +#define PVPLAYER_ENGINE_SDKINFO_LABEL "1511188" #define PVPLAYER_ENGINE_SDKINFO_DATE 0x20100622 #endif //PV_PLAYER_SDKINFO_H_INCLUDED diff --git a/fileformats/audioparser/amr/src/pvmf_amr_parser.cpp b/fileformats/audioparser/amr/src/pvmf_amr_parser.cpp index e9d8f85e3..a1e03a348 100644 --- a/fileformats/audioparser/amr/src/pvmf_amr_parser.cpp +++ b/fileformats/audioparser/amr/src/pvmf_amr_parser.cpp @@ -369,10 +369,6 @@ PVMFParserReturnCode PVMFAmrParser::Seek(int64 aSeekAt, int64& aSeekedTo) { LOG_DEBUG_MSG((0, "PVMFAmrParser::Seek() IN")); - if (0 == aSeekAt && iClipDuration == aSeekedTo) - // This means that node is stopping reset the FramesRead - iFramesRead = 0; - // Use the bitrate and frame len to do the seek OsclOffsetT offset = ((aSeekAt * ((iAmrBitrate + 7) / 8)) / 1000); uint32 numFrames = offset / iAvgFrameLen; @@ -382,8 +378,10 @@ PVMFParserReturnCode PVMFAmrParser::Seek(int64 aSeekAt, int64& aSeekedTo) return PVMFParserDefaultErr; aSeekedTo = aSeekAt; - LOG_DEBUG_MSG((0, "Seeked at timestamp %ld msec", aSeekedTo)); + // Set the FramesRead accordingly + iFramesRead = aSeekAt / TIME_STAMP_PER_FRAME; + LOG_DEBUG_MSG((0, "Seeked at timestamp %ld msec", aSeekedTo)); LOG_DEBUG_MSG((0, "PVMFAmrParser::Seek() OUT")); return PVMFParserEverythingFine; } diff --git a/fileformats/audioparser/wav/include/pvmf_wav_parser.h b/fileformats/audioparser/wav/include/pvmf_wav_parser.h index 2c6d64324..6f18c6f1c 100644 --- a/fileformats/audioparser/wav/include/pvmf_wav_parser.h +++ b/fileformats/audioparser/wav/include/pvmf_wav_parser.h @@ -25,8 +25,6 @@ #include "pvmi_ds_basic_interface.h" #endif -#define WAV_DATA_READ_IN_MSEC 100 - enum PVWavSupportedFormatType { WAV_FORMAT_UNKNOWN = 0, @@ -75,6 +73,8 @@ class PVMFWavParser: public PVMFFileParserInterface GAU* iGau; bool iEOSReached; PVLogger* ipLogger; + uint32 iBytesPerSec; + OsclSizeT iWavDataReadPerFrame; }; #endif diff --git a/fileformats/audioparser/wav/src/pvmf_wav_parser.cpp b/fileformats/audioparser/wav/src/pvmf_wav_parser.cpp index 2f65d6595..370078851 100644 --- a/fileformats/audioparser/wav/src/pvmf_wav_parser.cpp +++ b/fileformats/audioparser/wav/src/pvmf_wav_parser.cpp @@ -120,6 +120,8 @@ PVMFWavParser::PVMFWavParser() iFramesRead = 0; iEOSReached = false; ipLogger = PVLogger::GetLoggerObject("wavparser"); + iBytesPerSec = 0; + iWavDataReadPerFrame = 0; } PVMFWavParser::~PVMFWavParser() @@ -282,8 +284,8 @@ bool PVMFWavParser::Init(PvmiDataStreamInterface *aDataStream, int64 &aDuration, iEndDataChnkOffset = fileOffset + subChunkSize; - uint32 bytesPerSec = iBytesPerSample * iSamplesPerSec * iChannels; - aDuration = iDuration = ((iEndDataChnkOffset - iStartOffset) / bytesPerSec) * 1000; + iBytesPerSec = iBytesPerSample * iSamplesPerSec * iChannels; + aDuration = iDuration = ((iEndDataChnkOffset - iStartOffset) / iBytesPerSec) * 1000; aTimescale = 1000; return true; @@ -314,8 +316,10 @@ PVMFParserReturnCode PVMFWavParser::GetNextAccessUnits(GAU* aGau) if (PVDS_SUCCESS == status) { + iWavDataReadPerFrame = sizeInBytes; aGau->info[0].len = sizeInBytes; - aGau->info[0].ts = (iFramesRead * WAV_DATA_READ_IN_MSEC); + uint32 wavDataReadinMsec = (sizeInBytes * 1000) / iBytesPerSec; + aGau->info[0].ts = (iFramesRead * wavDataReadinMsec); iFramesRead++; if (pLawTable) { @@ -359,12 +363,8 @@ PVMFParserReturnCode PVMFWavParser::Seek(int64 aSeekAt, int64& aSeekedTo) { LOG_DEBUG_MSG((0, "PVMFWavParser: Seek In, seekAt %d", aSeekAt)); - if (0 == aSeekAt && iDuration == aSeekedTo) - // This means that node is stopping reset the FramesRead - iFramesRead = 0; - // Get the file offset toSeekTo - OsclOffsetT offsetSeekAt = ((aSeekAt * (iSamplesPerSec / iChannels)) / 1000) * iBytesPerSample; + OsclOffsetT offsetSeekAt = ((aSeekAt * iSamplesPerSec) / 1000) * iBytesPerSample * iChannels; // Now add the start offset offsetSeekAt += iStartOffset; @@ -380,8 +380,12 @@ PVMFParserReturnCode PVMFWavParser::Seek(int64 aSeekAt, int64& aSeekedTo) } // Seek on Datastream succedded, means we did seeked to offsetSeekAt, which means SeekAt msecs aSeekedTo = aSeekAt; + // Set the FramesRead accordingly + if (iWavDataReadPerFrame > 0) + iFramesRead = aSeekedTo / iWavDataReadPerFrame; // Reset EOS Boolean iEOSReached = false; + LOG_DEBUG_MSG((0, "PVMFWavParser: Seek Out, seekedTo %d", aSeekedTo)); return PVMFParserEverythingFine; } @@ -407,8 +411,10 @@ void PVMFWavParser::NotifyDataAvailable(OsclSizeT bytesRead, PvmiDataStreamStatu PVMFParserReturnCode retStatus = PVMFParserDefaultErr; if (PVDS_SUCCESS == aStatus) { + iWavDataReadPerFrame = bytesRead; iGau->info[0].len = bytesRead; - iGau->info[0].ts = (iFramesRead * WAV_DATA_READ_IN_MSEC); + uint32 wavDataReadinMsec = (bytesRead * 1000) / iBytesPerSec; + iGau->info[0].ts = (iFramesRead * wavDataReadinMsec); iFramesRead++; if (pLawTable) { diff --git a/nodes/pvcommonparsernode/include/pvmf_parser_defs.h b/nodes/pvcommonparsernode/include/pvmf_parser_defs.h index 6b5827af9..9a20f7d58 100644 --- a/nodes/pvcommonparsernode/include/pvmf_parser_defs.h +++ b/nodes/pvcommonparsernode/include/pvmf_parser_defs.h @@ -33,10 +33,10 @@ static const char PVMF_COMMON_PARSER_NODE_RANDOM_ACCESS_DENIED_KEY[] = "random-a // Tuneables for different fileformats #define PVMF_NUM_FRAMES_AMR 10 -#define PVMF_NUM_FRAMES_WAV 1102 +#define PVMF_MAX_FRAME_SIZE_AMR_NB 32 +#define PVMF_MAX_FRAME_SIZE_AMR_WB 61 -#define PVMF_FRAMES_BUFFER_LEN 2204 // This has to accomodate the biggest frame -// retrieved by the node. +#define PVMF_NUM_FRAMES_WAV 1102 #endif diff --git a/nodes/pvcommonparsernode/include/pvmf_parsernode_port.h b/nodes/pvcommonparsernode/include/pvmf_parsernode_port.h index b95c0aded..361a61ada 100644 --- a/nodes/pvcommonparsernode/include/pvmf_parsernode_port.h +++ b/nodes/pvcommonparsernode/include/pvmf_parsernode_port.h @@ -61,13 +61,16 @@ class PVMFParserNodeTrackPortInfo: public OsclMemPoolFixedChunkAllocatorObserver iTrackId = 0; iSeqNum = 0; iTimestamp = 0; + iSampleNPT = 0; iSampleDur = 0; iNumSamples = 1; + iBufferlen = 0; iSendBos = true; iSendEos = false; iEosSent = false; iOutgoingQueueBusy = false; iProcessOutgoingMsg = false; + iFirstFrameAfterSeek = false; ipMimeString = NULL; ipNode = NULL; ipPort = NULL; @@ -83,13 +86,16 @@ class PVMFParserNodeTrackPortInfo: public OsclMemPoolFixedChunkAllocatorObserver iTrackId = aSrc.iTrackId; iSeqNum = aSrc.iSeqNum; iTimestamp = aSrc.iTimestamp; + iSampleNPT = aSrc.iSampleNPT; iSampleDur = aSrc.iSampleDur; iNumSamples = aSrc.iNumSamples; + iBufferlen = aSrc.iBufferlen; iSendBos = aSrc.iSendBos; iSendEos = aSrc.iSendEos; iEosSent = aSrc.iEosSent; iOutgoingQueueBusy = aSrc.iOutgoingQueueBusy; iProcessOutgoingMsg = aSrc.iProcessOutgoingMsg; + iFirstFrameAfterSeek = aSrc.iFirstFrameAfterSeek; ipMimeString = aSrc.ipMimeString; ipNode = aSrc.ipNode; ipPort = aSrc.ipPort; @@ -123,25 +129,31 @@ class PVMFParserNodeTrackPortInfo: public OsclMemPoolFixedChunkAllocatorObserver { iSeqNum = 0; iTimestamp = 0; + iSampleNPT = 0; iSampleDur = 0; iNumSamples = 1; + iBufferlen = 0; iSendBos = true; iSendEos = false; iEosSent = false; iOutgoingQueueBusy = false; iProcessOutgoingMsg = false; + iFirstFrameAfterSeek = false; } uint32 iTrackId; uint32 iSeqNum; PVMFTimestamp iTimestamp; + PVMFTimestamp iSampleNPT; uint64 iSampleDur; uint32 iNumSamples; + uint32 iBufferlen; bool iSendBos; bool iSendEos; bool iEosSent; bool iOutgoingQueueBusy; bool iProcessOutgoingMsg; + bool iFirstFrameAfterSeek; char* ipMimeString; PVMFNodeInterfaceImpl* ipNode; PVMFPortInterface* ipPort; diff --git a/nodes/pvcommonparsernode/src/pvmf_parsernode_impl.cpp b/nodes/pvcommonparsernode/src/pvmf_parsernode_impl.cpp index 94d35e1fb..ac77d1424 100644 --- a/nodes/pvcommonparsernode/src/pvmf_parsernode_impl.cpp +++ b/nodes/pvcommonparsernode/src/pvmf_parsernode_impl.cpp @@ -152,10 +152,17 @@ PVMFStatus PVMFParserNodeImpl::GetMediaPresentationInfo(PVMFMediaPresentationInf if (iFileInfo.AudioPresent) { + // Check the Track type and set mime type and BufferLen to retrieve data if (PVMF_AMR_NB == iFileInfo.AudioTrkInfo.AudioFmt) + { mimeType = _STRLIT_CHAR(PVMF_MIME_AMR_IETF); + iTrackPortInfo.iBufferlen = PVMF_NUM_FRAMES_AMR * PVMF_MAX_FRAME_SIZE_AMR_NB; + } else if (PVMF_AMR_WB == iFileInfo.AudioTrkInfo.AudioFmt) + { mimeType = _STRLIT_CHAR(PVMF_MIME_AMRWB_IETF); + iTrackPortInfo.iBufferlen = PVMF_NUM_FRAMES_AMR * PVMF_MAX_FRAME_SIZE_AMR_WB; + } else if (PVMF_WAV_PCM == iFileInfo.AudioTrkInfo.AudioFmt) { if (8 == (iFileInfo.AudioTrkInfo.BitRate / iFileInfo.AudioTrkInfo.SamplingRate)) @@ -171,6 +178,13 @@ PVMFStatus PVMFParserNodeImpl::GetMediaPresentationInfo(PVMFMediaPresentationInf mimeType = _STRLIT_CHAR(PVMF_MIME_ULAW); else status = PVMFErrNotSupported; + + if (0 == iTrackPortInfo.iBufferlen) + { + // Just set it for WAV parser + uint32 bytesPerSample = ((iFileInfo.AudioTrkInfo.BitRate / iFileInfo.AudioTrkInfo.SamplingRate) + 7) / 8; + iTrackPortInfo.iBufferlen = PVMF_NUM_FRAMES_WAV * iFileInfo.AudioTrkInfo.NoOfChannels * bytesPerSample; + } } aInfo.setDurationValue(iClipDuration); @@ -447,7 +461,7 @@ PVMFStatus PVMFParserNodeImpl::DoStop() (&iTrkPortInfoVec[0])->reset(); // Reset the tracks - int64 seekTo = iClipDuration; // This is to let the parser know that this seek is requested while stopping the node + int64 seekTo = 0; ipParser->Seek(0, seekTo); PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFParserNodeImpl::DoStop: Out")); @@ -575,7 +589,12 @@ void PVMFParserNodeImpl::ProcessPortActivity(PVMFParserNodeTrackPortInfo* aTrack if (SendBeginOfMediaStreamCommand(aTrackPortInfo->ipPort, iStreamID, aTrackPortInfo->iTimestamp)) aTrackPortInfo->iSendBos = false; else + { + // Queue is not ready to accept any more data, set the boolean iOutgoingQueueBusy as true + // and wait for Queues to signal when they are ready + aTrackPortInfo->iOutgoingQueueBusy = true; return; + } } if (!aTrackPortInfo->iSendEos) @@ -602,12 +621,12 @@ PVMFStatus PVMFParserNodeImpl::QueueMediaSample(PVMFParserNodeTrackPortInfo* aTr { // Create a Media data pool OsclSharedPtr mediaDataImpl; - mediaDataImpl = aTrackPortInfo->ipResizeableSimpleMediaMsg->allocate(PVMF_FRAMES_BUFFER_LEN); + mediaDataImpl = aTrackPortInfo->ipResizeableSimpleMediaMsg->allocate(aTrackPortInfo->iBufferlen); if (NULL == mediaDataImpl.GetRep()) { OsclMemPoolResizableAllocatorObserver* resizableMemPoolAllocObs = OSCL_STATIC_CAST(OsclMemPoolResizableAllocatorObserver*, aTrackPortInfo); - aTrackPortInfo->ipResizeableMemPoolAllocator->notifyfreeblockavailable(*resizableMemPoolAllocObs, PVMF_FRAMES_BUFFER_LEN); + aTrackPortInfo->ipResizeableMemPoolAllocator->notifyfreeblockavailable(*resizableMemPoolAllocObs, aTrackPortInfo->iBufferlen); PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipDatapathLog, PVLOGMSG_STACK_TRACE, (0, "PVMFParserNodeImpl::QueueMediaSample: No Memory available")); return PVMFErrNoMemory; } @@ -619,7 +638,7 @@ PVMFStatus PVMFParserNodeImpl::QueueMediaSample(PVMFParserNodeTrackPortInfo* aTr { OsclMemPoolResizableAllocatorObserver* resizableMemPoolAllocObs = OSCL_STATIC_CAST(OsclMemPoolResizableAllocatorObserver*, aTrackPortInfo); - aTrackPortInfo->ipResizeableMemPoolAllocator->notifyfreeblockavailable(*resizableMemPoolAllocObs, PVMF_FRAMES_BUFFER_LEN); + aTrackPortInfo->ipResizeableMemPoolAllocator->notifyfreeblockavailable(*resizableMemPoolAllocObs, aTrackPortInfo->iBufferlen); PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipDatapathLog, PVLOGMSG_STACK_TRACE, (0, "PVMFParserNodeImpl::QueueMediaSample: No Memory available")); return PVMFErrNoMemory; } @@ -632,12 +651,12 @@ PVMFStatus PVMFParserNodeImpl::QueueMediaSample(PVMFParserNodeTrackPortInfo* aTr { ipGau->MediaBuffer = NULL; ipGau->NumberOfFrames = PVMF_NUM_FRAMES_AMR; - ipGau->BufferLen = PVMF_FRAMES_BUFFER_LEN; + ipGau->BufferLen = aTrackPortInfo->iBufferlen; } else if (iClipFmtType == PVMF_MIME_WAVFF) { ipGau->MediaBuffer = (uint8*)refCntrMemFrag.getMemFragPtr(); - ipGau->BufferLen = PVMF_FRAMES_BUFFER_LEN; + ipGau->BufferLen = aTrackPortInfo->iBufferlen; ipGau->NumberOfFrames = PVMF_NUM_FRAMES_WAV; } @@ -656,9 +675,21 @@ PVMFStatus PVMFParserNodeImpl::QueueMediaSample(PVMFParserNodeTrackPortInfo* aTr // Resize Memory Fragment aTrackPortInfo->ipResizeableSimpleMediaMsg->ResizeMemoryFragment(mediaDataImpl); + // Special handling for first frame after seek + if (aTrackPortInfo->iFirstFrameAfterSeek) + { + aTrackPortInfo->iSampleNPT = ipGau->info[0].ts; + aTrackPortInfo->iFirstFrameAfterSeek = false; + } + + // Sample Duration of first sample after seek will be zero. The duration can only be known once node + // has retrieved atleast 2 samples. + aTrackPortInfo->iSampleDur = ipGau->info[0].ts - aTrackPortInfo->iSampleNPT; + aTrackPortInfo->iTimestamp += aTrackPortInfo->iSampleDur; + aTrackPortInfo->iSampleNPT = ipGau->info[0].ts; + // Set the parameters mediaDataPtr->setStreamID(iStreamID); - aTrackPortInfo->iTimestamp = ipGau->info[0].ts; mediaDataPtr->setTimestamp(aTrackPortInfo->iTimestamp); mediaDataPtr->setSeqNum(aTrackPortInfo->iSeqNum); PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipDatapathLog, PVLOGMSG_STACK_TRACE, @@ -726,11 +757,12 @@ PVMFStatus PVMFParserNodeImpl::DoSetDataSourcePosition() for (uint32 ii = 0; ii < iTrkPortInfoVec.size(); ii++) { - // New stream reset BOS-EOS booleans and start the data flow + // New stream reset booleans for BOS-EOS and start the data flow iTrkPortInfoVec[ii].iSendBos = true; iTrkPortInfoVec[ii].iSendEos = false; iTrkPortInfoVec[ii].iEosSent = false; iTrkPortInfoVec[ii].iOutgoingQueueBusy = false; + iTrkPortInfoVec[ii].iFirstFrameAfterSeek = true; if (sendBosEos) // Since the target position was beyond clip duration source just needs // to send EOS after BOS, so set the boolean for EOS