[datatype-dev] CR: Rebuffering of Video only presenation when video stream is running behind
Milko Boic milko at real.com
Forgot to scale the LateFrameRebufferingTolerance by playback acceleration
factors (trick-play).
Here is corrected CheckForBufferingStart:
void CVideoRenderer::CheckForBufferingStart()
{
if (m_ulVideoBufferingPreference == 0)
{
// Video Buffering disabled
return;
}
else
{
if (m_pVideoFormat &&
!m_pVideoFormat->OnRawPacketsEnded())
{
lTimeDelta = ComputeTimeAhead(m_ulActiveVideoTime, 0);
if ((m_ulAbsPlaybackVelocity !=
HX_PLAYBACK_VELOCITY_NORMAL) &&
(m_ulAbsPlaybackVelocity != 0))
{
lTimeDelta = ((lTimeDelta *
HX_PLAYBACK_VELOCITY_NORMAL) /
((INT32) m_ulAbsPlaybackVelocity));
}
if (((INT32) (lTimeDelta +
GetLateFrameRebufferingTolerance())) < 0)
{
if ((m_ulVideoBufferingPreference == 2) &&
!IsVideoOnlyPlayback())
{
// Video buffering disabled for
non-video only playback
return;
}
RequestBuffering();
}
}
}
}
---------------------
The implementation has a few issues:
1.)
REBUFFER_ON_VIDEO should be enabled and controlled by a preference:
"RebufferOnVideo".
Default should be 0 (do not rebuffer on video).
You can retrieve the preference value at the bottom of ::OnHeader method.
Values:
0 = do not rebuffer on video
1 = rebuffer on video
2 = rebuffer if video only playback
2.)
+UINT16
+CVideoRenderer::CheckForNumStreams()
+{
The above should be changed to CVideoRenderer::IsVideoOnlyPlayback() .
This routine should obtain IHXAudioPlayer from the source and check for
pAudioPlayer->GetAudioStreamCount() != 0 .
The NULL pointers must be checked. We should not assert. Renderer
component may be run in environments where audio player is not
available. We need to handle such case for defaulting to default case of
not being a video only playback.
That is, we should assume it is not video only playback unless confirmed
otherwise.
3.)
Remove all added member vars - they are not needed:
ulBaseTime - available from m_pTimeSyncSmoother->GetBaseTime() and not needed
m_bIsBaseTimeSet - not needed
m_ulLastFrameTime - not needed, m_ulActiveVideoTime is available (merge
from HEAD if needed)
4.)
+ if(pPacket && !(pPacket->IsLost()))
+ {
+ m_ulLastFrameTime = pPacket->GetTime();
+ m_lTimeOffset = lTimeOffset;
+ }
Setting the frame time in OnPacket call is conceptually wrong and
inaccurate. Packet is delivered well ahead of playback time and such check
does not capture freezing of video due to either packets consistently
arriving late or due to CPU constraints making the decoded frames
late. What needs to be compared is last renderer frame displayed and
current playback time. More precisely, we need to see how far behind the
playtime currently displayed frame is. In general, it is difficult to use
a constant to check against since video frame rate can vary and it is also
possible for a video stream to enter a key-frame only mode (RealVideo)
during low bandwidth conditions. In such mode it is not unusual for
key-frames to be 10 seconds or more apart. It is precisely for this reason
that video is really a pseudo-contiguous media and could not be reliably
used for re-buffering. To mitigate this situation, a new virtual method
GetLateFrameRebufferingTolerance() be called from the base video renderer
that can be overriden in the derived renderers (e.g. RealVideo or
Mpeg4Video) to provide proper time interval threshold of un-displayed
frames to cause re-buffering. This way the value can be set appropriately
for different data-types.
This check should be placed in ::SchedulerCallback() method in couple of
places where we :
a.)
else
{
+ CheckForBufferingStart();
if (bResched)
{
ScheduleCallback(m_ulNoFramesPollingInterval);
}
DisplayMutex_Unlock();
if (m_pVideoFormat &&
m_pVideoFormat->IsFillbackDecodeNeeded())
{
m_pVideoFormat->DecodeFrame();
}
return;
}
b.)
if ((m_PlayState != Stopped) &&
bResched)
{
+ CheckForBufferingStart();
ScheduleCallback(NO_FRAMES_POLLING_INTERVAL);
DisplayMutex_Unlock();
if (m_pVideoFormat &&
m_pVideoFormat->IsFillbackDecodeNeeded() &&
(!m_bServicingFillbackDecode))
{
m_bServicingFillbackDecode = TRUE;
m_pVideoFormat->DecodeFrame();
m_bServicingFillbackDecode = FALSE;
}
return;
}
void CVideoRenderer::CheckForBufferingStart()
{
if (m_ulVideoBufferingPreference == 0)
{
// Video Buffering disabled
return;
}
else
{
if (m_pVideoFormat &&
!m_pVideoFormat->OnRawPacketsEnded() &&
ComputeTimeAhead(m_ulActiveVideoTime,
GetLateFrameRebufferingTolerance()) < 0)
{
if ((m_ulVideoBufferingPreference == 2) &&
!IsVideoOnlyPlayback())
{
// Vide buffering disabled for non-video
only playback
return;
}
RequestBuffering();
}
}
}
5.)
When OnEndofPackets is called (no more data will be arriving), make sure
to end any buffering currently in progress:
STDMETHODIMP CVideoRenderer::OnEndofPackets(void)
{
HXLOGL3(HXLOG_BVID, "CVideoRenderer::OnEndofPackets()");
if (m_pVideoFormat)
{
m_pVideoFormat->OnRawPacketsEnded();
}
m_pMutex->Lock();
EndBuffering();
m_pMutex->Unlock();
return HXR_OK;
}
6.)
Termninate buffering when ::OnPreSeek() call is issued:
STDMETHODIMP CVideoRenderer::OnEndofPackets(void)
{
STDMETHODIMP CVideoRenderer::OnPreSeek(ULONG32 ulOldTime, ULONG32 ulNewTime)
{
HXLOGL3(HXLOG_BVID, "CVideoRenderer::OnPreSeek(OldTime=%lu,
NewTime=%lu)", ulOldTime, ulNewTime);
// Change state to stop Blts
m_pMutex->Lock();
EndBuffering();
m_PlayState = Seeking;
m_pMutex->Unlock();
At 03:22 AM 10/31/2006, Lovish Dhawan wrote:
>Synopsis:
>This change is to fix REBUFFER_ON_VIDEO support. Needed by CE manufactures
>who want to use this feature to pause the timeline when video is running
>behind (to avoid video freeze).
>
>Overview:
>This change fixes for Rebuffering of Video only presentation when video
>stream is running behind.
>
>Files Added:
>
>Files Modified:
>datatype/common/vidrend/vidrend.cpp -
>datatype/common/vidrend/vidrend.h -
>
>Image Size and Heap Use impact (Client -Only):
>None.
>
>Platforms and Profiles Affected:
>None. (This feature is to be explicitly enabled)
>
>Distribution Libraries Affected:
>None
>
>Distribution library impact and planned action:
>None
>
>Platforms and Profiles Build Verified:
>BIF branch -> hxclient_1_5_0_cayenne_restricted
>Target(s) ->splay
>Profile ->helix-client-mobile-ezx
>SYSTEM_ID=linux-2.2-libc6-gcc32-i586
>
>Branch:
>HEAD, hxclient_1_5_0_cayenne
>
>Files Attached:
>Vidrend.zip containing the 2 diff files Vidrend.cpp.diff and vidrend.h.diff
>
>Regards,
>Lovish
>
>_______________________________________________
>Datatype-dev mailing list
>Datatype-dev at helixcommunity.org
>http://lists.helixcommunity.org/mailman/listinfo/datatype-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.helixcommunity.org/pipermail/datatype-dev/attachments/20061117/c0c4e950/attachment.html