Thanks Rajesh
Find below updated CVS Diff . I changed the logic of time computation and
it is now based on samples written in to the buffer instead of
SamplesPlayed() symbian call. I observed that audio device start playing
after it gets two buffer filled.
In this logic I added three sample count member which keep track of last
3 buffers. As soon as two buffers are filled by BufferToBeFilled()
function the current tick count is recorded. The deltaTime is computed
based on this tickcount and sent in subsequent getTime calls based on the
lasttolast buffer time. Each time a new buffer is completed the reference
time is shifted to the next buffer time and all delta time are now
calculated based on this buffer. It will help in resetting the error
accrued in computing the delta time and also helps in handling Pause.
The old logic of SamplesPlayed is also kept under #if defined
HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED and it can be activated by defining
this constant.
Let me know your suggestions.
CVS Diff
Index: audio_session-mmf.cpp
===================================================================
RCS file:
/cvsroot/audio/device/platform/symbian/audiosvr/mmf/audio_session-mmf.cpp,v
retrieving revision 1.4.2.6
diff -u -r1.4.2.6 audio_session-mmf.cpp
--- audio_session-mmf.cpp 20 Apr 2005 23:50:58 -0000 1.4.2.6
+++ audio_session-mmf.cpp 13 Apr 2006 12:59:14 -0000
@@ -201,12 +201,21 @@
m_pPendingFillBuffer(NULL),
m_cbFrontBufferWritten(0),
m_samplesWritten(0),
+#if defined HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED
m_lastSampleCount(0),
m_unplayedSampleCount(0),
m_msTimePlayed(0),
m_sampleCountResetPending(FALSE),
m_resetTriggerSampleCount(0),
m_resetTriggerUnplayedCount(0)
+#else
+ m_TotalSamplesWritten(0),
+ m_ulStartTime(0),
+ m_TotalSamplesFillLastToLastBuff(0),
+ m_TotalSamplesFillLastBuff(0),
+ m_TotalSamplesFillBuff(0),
+ m_ulReportedTime(0)
+#endif
{
// add the session to the server
HX_ASSERT(m_pServer);
@@ -495,6 +504,8 @@
HX_ASSERT(!m_pPendingFillBuffer);
}
}
+
+#if defined HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED
void HXSymbianAudioSession::OnResetSampleCount()
{
@@ -652,14 +663,28 @@
OnNewSampleCount(sampleCount);
UpdateUnplayedSampleCount();
}
+#endif // HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED
//
// HXSymbianAudioSession::GetTime
//
void HXSymbianAudioSession::GetTime()
{
+#if defined (HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED)
UpdateTimeSampleStats();
Message().Complete(m_msTimePlayed);
+#else
+ if((m_state == PLAYING )&& m_TotalSamplesFillLastBuff)
+ {
+ ULONG32 ulDeltaTime = HX_GET_BETTERTICKCOUNT() - m_ulStartTime;
+ m_ulReportedTime =
SamplesToMS((m_TotalSamplesFillLastToLastBuff), m_sampleRate)+ulDeltaTime;
+ Message().Complete(m_ulReportedTime);
+ }
+ else
+ {
+ Message().Complete(m_ulReportedTime);
+ }
+#endif // HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED
}
@@ -672,10 +697,13 @@
void HXSymbianAudioSession::GetBlocksBuffered()
{
// determine bytes buffered in actual device
- UpdateTimeSampleStats();
HX_ASSERT(m_cbSample != 0);
- UINT32 cbBuffered = m_unplayedSampleCount * m_cbSample;
+ UINT32 cbBuffered = 0;
+#if defined HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED
+ UpdateTimeSampleStats();
+ cbBuffered = m_unplayedSampleCount * m_cbSample;
+#endif
// add in bytes we are holding in our buffer list
HX_ASSERT(m_cbBufferList >= m_cbFrontBufferWritten);
cbBuffered += m_cbBufferList - m_cbFrontBufferWritten;
@@ -762,12 +790,21 @@
case PLAYINIT_PENDING:
case PAUSED:
Trans(STOPPED);
- HXLOGL3(HXLOG_ADEV, "HXSymbianAudioSession::Stop(): %lu ms
unplayed in audio device", SamplesToMS(m_unplayedSampleCount, m_sampleRate));
+ // HXLOGL3(HXLOG_ADEV, "HXSymbianAudioSession::Stop(): %lu ms
unplayed in audio device", SamplesToMS(m_unplayedSampleCount, m_sampleRate));
m_pStream->Stop();
// do additional stuff associated with user stop
FreePendingBuffers();
+#if defined HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED
m_msTimePlayed = 0;
+#else
+ m_TotalSamplesWritten = 0;
+ m_ulStartTime = 0;
+ m_TotalSamplesFillLastToLastBuff = 0;
+ m_TotalSamplesFillLastBuff = 0;
+ m_TotalSamplesFillBuff = 0;
+ m_ulReportedTime = 0;
+#endif
break;
default:
// nothing
@@ -849,6 +886,7 @@
//
void HXSymbianAudioSession::PrepareForDeviceReset()
{
+#if defined HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED
HX_ASSERT(!m_sampleCountResetPending);
if (KErrNone == m_lastPlayError)
@@ -870,7 +908,7 @@
}
m_sampleCountResetPending = TRUE;
-
+#endif
// this tracks samples written after device reset trigger
m_samplesWritten = 0;
@@ -1022,8 +1060,11 @@
// keep track of how many full samples we write
HX_ASSERT(0 == (cbToWrite % m_cbSample));
- m_samplesWritten += (cbToWrite / m_cbSample);
-
+ UINT32 ulSamplesWritten = (cbToWrite / m_cbSample);
+ m_samplesWritten += ulSamplesWritten;
+#if !defined HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED
+ m_TotalSamplesWritten += ulSamplesWritten;
+#endif
if (m_cbFrontBufferWritten == cbBuffer)
{
// we used up the front buffer; toss it
@@ -1044,6 +1085,15 @@
m_pStream->PlayData();
}
m_pPendingFillBuffer = NULL;
+#if !defined HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED
+ m_TotalSamplesFillLastToLastBuff = m_TotalSamplesFillLastBuff;
+ m_TotalSamplesFillLastBuff = m_TotalSamplesFillBuff;
+ m_TotalSamplesFillBuff = m_TotalSamplesWritten;
+ if(m_TotalSamplesFillLastBuff)
+ {
+ m_ulStartTime = HX_GET_BETTERTICKCOUNT();
+ }
+#endif
}
else
{
@@ -1051,8 +1101,9 @@
// hold on to buffer; we'll fill it once we have more src data
m_pPendingFillBuffer = aBuffer;
}
-
+#if defined (HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED)
UpdateTimeSampleStats();
+#endif
}
Index: audio_session-mmf.h
===================================================================
RCS file:
/cvsroot/audio/device/platform/symbian/audiosvr/mmf/audio_session-mmf.h,v
retrieving revision 1.5.2.3
diff -u -r1.5.2.3 audio_session-mmf.h
--- audio_session-mmf.h 20 Apr 2005 03:22:48 -0000 1.5.2.3
+++ audio_session-mmf.h 13 Apr 2006 12:59:15 -0000
@@ -113,11 +113,15 @@
// helpers
void DoPlayInit(HXBOOL setPriority = TRUE);
+
+#if defined HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED
void UpdateTimeSampleStats();
void UpdateUnplayedSampleCount();
void OnNewSampleCount(UINT32 sampleCount);
void CheckSampleCountReset(TUint sampleCount);
void OnResetSampleCount();
+#endif
+
void PrepareForDeviceReset();
void FreePendingBuffers();
@@ -149,7 +153,7 @@
TUint m_cbFrontBufferWritten;
TUint m_samplesWritten;
-
+ #if defined HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED
// audio time related
TUint m_lastSampleCount;
TUint m_unplayedSampleCount;
@@ -157,8 +161,14 @@
HXBOOL m_sampleCountResetPending;
TUint m_resetTriggerSampleCount;
TUint m_resetTriggerUnplayedCount;
-
-
+#else
+ UINT32 m_TotalSamplesWritten;
+ UINT32 m_ulStartTime;
+ UINT32 m_TotalSamplesFillLastToLastBuff;
+ UINT32 m_TotalSamplesFillLastBuff;
+ UINT32 m_TotalSamplesFillBuff;
+ UINT32 m_ulReportedTime;
+#endif
};
#endif // _AUDIO_SESSION_H_
Thanks and Regards
Pankaj Gupta
At 08:07 PM 4/12/2006, [EMAIL PROTECTED] wrote:
Pankaj,
Timing calculation can be configured to use samples written or
samples played. The compiler define for it is
HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED. If this flag is defined then audio
session will use SamplesPlayed API to calculate time.
We did notice AV Sync problem on 8Khz sampling rate alone when the above
flag was not defined (ie while using samples written calculation). After
turning on the HELIX_CONFIG_SYMBIAN_SAMPLESPLAYED flag, there is no AV
sync.
Using Systemtime is somewhat similar to using the SamplesWritten
calculation. If DevSound takes a little longer time to output the data,
then we will still have the AV sync issue.
Regards,
Rajesh.
>-----Original Message-----
>From: ext Pankaj Gupta [mailto:[EMAIL PROTECTED]
>Sent: Wednesday, April 12, 2006 8:54 AM
>To: Rathinasamy Rajesh (Nokia-TP-MSW/Dallas); [EMAIL PROTECTED]
>Cc: audio-dev@helixcommunity.org
>Subject: RE: [Audio-dev] CR: Fix to improve symbian player performance
>
>Hi Rajesh
>
>Thanks for suggestions.
>
>I verified that the problem is not because of pause. I also
>looked into the 210cays code and here the time calculation is
>based on the number of samples written into the buffer instead
>of SamplesPlayed call. But when I put there same logic in
>150cay the audio Video sync was lost and audio started lagging
>behind Video. I am trying to put some workaround in GetTime so
>that I can use SytemTime along with the 210s logic to resolve
>this issue. Just need to verify did anyone noticed audio video
>sinking problem on 210CayS?
>
>Regards
>Pankaj
>
>
>At 11:48 PM 4/11/2006, [EMAIL PROTECTED] wrote:
>>Greg & Pankaj,
>> SamplePlayed count used to reset on pause for 6630. Code has been
>>added to handle this case. I think the code should be
>available for 150
>>cay too. But the handling was initially enabled only for 6630. Later
>>Dextra found the same problem for 6680 and updated the check
>to enable
>>for that device too.
>>
>>It may be worth looking in that too. (
>>HXSymbianAudioSession::HXSymbianAudioSession) Just try
>turning on that
>>boolean variable to see whether it solves your problem.
>>
>>TInt uid = 0;
>> TInt res = HAL::Get(HALData::EMachineUid, uid);
>> if (KErrNone == res)
>> {
>> if (DEVICE_UID_6630 == uid || DEVICE_UID_6680 == uid )
>> {
>> m_deviceResetsOnPause = TRUE;
>> }
>> HXLOGL3(HXLOG_ADEV,
>>"HXSymbianAudioSession::HXSymbianAudioSession(): symbian device uid =
>>0x%08x", uid);
>> }
>>
>>210Cay also has some code to accommodate lost samples during
>pause case.
>>
>>
>> For all Symbian 9.x, this flag is turned on.
>>
>>-Rajesh.
>>
>>
>> >-----Original Message-----
>> >From: ext Greg Wright [mailto:[EMAIL PROTECTED]
>> >Sent: Tuesday, April 11, 2006 1:08 PM
>> >To: Rathinasamy Rajesh (Nokia-TP-MSW/Dallas)
>> >Cc: [EMAIL PROTECTED]; audio-dev@helixcommunity.org
>> >Subject: Re: [Audio-dev] CR: Fix to improve symbian player
>> >performance
>> >
>> >[EMAIL PROTECTED] wrote:
>> >> Hi Pankaj,
>> >> Even though Audio session writes data in chunks to DevSound,
>> >> the SamplesPlayed API is supposed to report the samples
>Played stat
>> >> in real time. It should not wait for the complete playout of data
>> >> to report samples played. For example even if u write 200msecs
>> >of data in
>> >> one shot, the samplesPlayed will be queried for every 30msec
>> >interval
>> >> and the samplesplayed api should start reporting the progress
>> >> counts instead of waiting for 200msec to playout.
>> >>
>> >> Now the code increases the number of BTBF
>(BufferToBeFilled ) calls.
>> >> More number of BTBF calls results in that many server-client
>> >> interaction (and also that many copy on buffers
>> >descriptor)on the DevSound layer.
>> >>
>> >> Apart from that the Audio buffer flow between AudioSession and
>> >> Engine's audio layer is already throttled by BlocksBufferred
>> >API. Too
>> >> much of data accumulation would not happen on the Audio session.
>> >> The Supply of data will be cut down from engine's Audio
>Service to
>> >> Audio-session which means u may not have lot of data in
>AudioSession.
>> >>
>> >> If SamplesPlayed reporting is jumping in a big number, then this
>> >> change might actually hide the problem in DevSound.
>> >>
>> >> What version of Symbian u r running ? (Is that Series 60 or UIQ )
>> >
>> >FYI,
>> >
>> >Pankaj is trying to fix playback problems on a Nokia 6600.
>The 150Cay
>> >branch does not playback as well as the 142NepX branch.
>> >
>> >--greg.
>> >
>> >
>> >>
>> >> Hope it helps !
>> >>
>> >> Thanks,
>> >> Rajesh.
>> >>
>> >>
>> >>
>> >>
>> >>> -----Original Message-----
>> >>> From: [EMAIL PROTECTED]
>> >>> [mailto:[EMAIL PROTECTED] On Behalf Of
>> >ext Pankaj
>> >>> Gupta
>> >>> Sent: Tuesday, April 11, 2006 5:33 AM
>> >>> To: audio-dev@helixcommunity.org
>> >>> Subject: [Audio-dev] CR: Fix to improve symbian player
>performance
>> >>>
>> >>> Modified by: [EMAIL PROTECTED]
>> >>>
>> >>> Date :11/04/2006
>> >>>
>> >>> Issue :Performance issue in 150 cayenne symbian player
>> >>>
>> >>> Overview:
>> >>>
>> >>> In 150Cayenne symbian player video is not smooth and
>> >observed visible
>> >>> frame dropping usually once per second.
>> >>> This is happening because the audio device is not driving time
>> >>> line smoothly.
>> >>>
>> >>> In
>> >>> audio\device\platform\symbian\audiosvr\mmf\audio_session-mmf.cp
>> >>> p file the time calculation is based on SamplesPlayed
>returned by
>> >>> device/samplingRate.
>> >>>
>> >>> The HXSymbianAudioSession::BufferToBeFilled() function writes
>> >>> large amount of data in device because of which
>> >>> m_pStream->SamplesPlayed() function returns same value for
>> >quite some
>> >>> time and then suddenly returns higher value causing sudden time
>> >>> change of the tune of ~500ms.
>> >>>
>> >>> Fix.
>> >>>
>> >>> In HXSymbianAudioSession::BufferToBeFilled() function is
>> >writing only
>> >>> one buffer from the m_bufferList at a time. This same fix
>> >was applied
>> >>> in 142NeptuneX branch also.
>> >>>
>> >>> Platform: symbian
>> >>>
>> >>> Branch : 150Cay
>> >>>
>> >>> File Modified:
>> >>>
>> >>> -
>audio/device/platform/symbian/audiosvr/mmf/audio_session-mmf.cpp
>> >>>
>> >>> Files Added: Nil
>> >>>
>> >>> Thanks and Regards,
>> >>> Pankaj Gupta
>> >>>
>> >>> CVS Diff:
>> >>>
>> >>> Index: audio_session-mmf.cpp
>> >>>
>==================================================================
>> >>> =
>> >>> RCS file:
>> >>> /cvsroot/audio/device/platform/symbian/audiosvr/mmf/audio_sessi
>> >>> on-mmf.cpp,v
>> >>> retrieving revision 1.4.2.6
>> >>> diff -u -w -r1.4.2.6 audio_session-mmf.cpp
>> >>> --- audio_session-mmf.cpp 20 Apr 2005 23:50:58 -0000
> 1.4.2.6
>> >>> +++ audio_session-mmf.cpp 11 Apr 2006 10:30:54 -0000
>> >>> @@ -981,7 +981,12 @@
>> >>>
>> >>> //HXLOGL4(HXLOG_ADEV,
>> >>> "HXSymbianAudioSession::BufferToBeFilled(): req size = %ld; dest
>> >>> buffer size = %lu; desc max = %lu; buffer list count = %ld",
>> >>> aBuffer->RequestSize(), aBuffer->BufferSize(),
>dataDesc.MaxSize(),
>> >>> m_bufferList.GetCount());
>> >>>
>> >>> - while ( !m_bufferList.IsEmpty() && cbDest >= m_cbSample)
>> >>> + // Used if statement in place of while as writing
>> >complete data
>> >>> + causes
>> >>> sudden
>> >>> + // large time differences in GetTime() calls. Since
>> >>> m_pStream->SamplesPlayed()
>> >>> + // returns same value for quite some time and then
>> >>> suddenly returns
>> >>> higher value,
>> >>> + // which causes sudden jump of around 300ms-700ms
>in GetTime
>> >>> + calls
>> >>> causing
>> >>> + // TimeSync problem and frame dropping in vidrend.cpp
>> >>> + if ( !m_bufferList.IsEmpty() && cbDest >= m_cbSample)
>> >>> {
>> >>> // get buffer at front
>> >>> IHXBuffer* pBuffer = (IHXBuffer*)m_bufferList.GetHead();
>> >>>
>> >>>
>> >>> _______________________________________________
>> >>> Audio-dev mailing list
>> >>> Audio-dev@helixcommunity.org
>> >>> http://lists.helixcommunity.org/mailman/listinfo/audio-dev
>> >>>
>> >>
>> >> _______________________________________________
>> >> Audio-dev mailing list
>> >> Audio-dev@helixcommunity.org
>> >> http://lists.helixcommunity.org/mailman/listinfo/audio-dev
>> >>
>> >
>
>
>