Skip to content
This repository
Browse code

[rbp] Set mediatime on GPU after a seek.

Currently after a seek, the mediatime doesn't update until an audio and video packet have been fetched from demuxer, and been decoded. For HD content this can take a second or two.
This has a couple of undesirable effects:
The seek time that pops up after a seek initially shows the before seek time, and the file progress bar is laggy.
If you seek a second time, before the time has updated, it will use the before seek time, and the second seek has no effect.
This limits a sequence of seeks to a maximum of about 1 every second or two.

The fix udpates the GPU mediatime immediately after the seek, so the mediatime is correct immediately which fixes the undesirable behaviour.
  • Loading branch information...
commit c106cfd4e35dd53310d7325ce658618807d59ac2 1 parent 3caf659
popcornmix authored March 17, 2013
3  xbmc/cores/omxplayer/OMXPlayer.cpp
@@ -3296,6 +3296,9 @@ void COMXPlayer::FlushBuffers(bool queued, double pts, bool accurate)
3296 3296
     CSingleLock lock(m_StateSection);
3297 3297
     m_State = m_StateInput;
3298 3298
   }
  3299
+  // let clock know the new time so progress bar updates immediately
  3300
+  if(startpts != DVD_NOPTS_VALUE)
  3301
+    m_av_clock.OMXMediaTime(startpts);
3299 3302
 }
3300 3303
 
3301 3304
 // since we call ffmpeg functions to decode, this is being called in the same thread as ::Process() is
46  xbmc/linux/OMXClock.cpp
@@ -745,6 +745,52 @@ double OMXClock::OMXMediaTime(bool fixPreroll /* true */ , bool lock /* = true *
745 745
   return pts;
746 746
 }
747 747
 
  748
+// Set the media time, so calls to get media time use the updated value,
  749
+// useful after a seek so mediatime is updated immediately (rather than waiting for first decoded packet)
  750
+bool OMXClock::OMXMediaTime(double pts, bool fixPreroll /* = true*/, bool lock /* = true*/)
  751
+{
  752
+  if(m_omx_clock.GetComponent() == NULL)
  753
+    return false;
  754
+
  755
+  if(lock)
  756
+    Lock();
  757
+
  758
+  OMX_ERRORTYPE omx_err = OMX_ErrorNone;
  759
+  OMX_INDEXTYPE index;
  760
+  OMX_TIME_CONFIG_TIMESTAMPTYPE timeStamp;
  761
+  OMX_INIT_STRUCTURE(timeStamp);
  762
+  timeStamp.nPortIndex = m_omx_clock.GetInputPort();
  763
+
  764
+  if(g_guiSettings.GetBool("videoplayer.usedisplayasclock") && m_has_video)
  765
+    index = OMX_IndexConfigTimeCurrentVideoReference;
  766
+  else if(m_has_audio)
  767
+    index = OMX_IndexConfigTimeCurrentAudioReference;
  768
+  else
  769
+    index = OMX_IndexConfigTimeCurrentVideoReference;
  770
+
  771
+  if(fixPreroll)
  772
+    pts -= (OMX_PRE_ROLL * 1000);
  773
+  timeStamp.nTimestamp = ToOMXTime(pts);
  774
+
  775
+  omx_err = m_omx_clock.SetConfig(index, &timeStamp);
  776
+  if(omx_err != OMX_ErrorNone)
  777
+  {
  778
+    CLog::Log(LOGERROR, "OMXClock::OMXMediaTime error setting %s", index == OMX_IndexConfigTimeCurrentAudioReference ?
  779
+       "OMX_IndexConfigTimeCurrentAudioReference":"OMX_IndexConfigTimeCurrentVideoReference");
  780
+    if(lock)
  781
+      UnLock();
  782
+    return false;
  783
+  }
  784
+
  785
+  CLog::Log(LOGDEBUG, "OMXClock::OMXMediaTime set config %s = %.2f", index == OMX_IndexConfigTimeCurrentAudioReference ?
  786
+       "OMX_IndexConfigTimeCurrentAudioReference":"OMX_IndexConfigTimeCurrentVideoReference", pts);
  787
+
  788
+  if(lock)
  789
+    UnLock();
  790
+
  791
+  return true;
  792
+}
  793
+
748 794
 bool OMXClock::OMXPause(bool lock /* = true */)
749 795
 {
750 796
   if(m_omx_clock.GetComponent() == NULL)
1  xbmc/linux/OMXClock.h
@@ -116,6 +116,7 @@ class OMXClock
116 116
   bool OMXReset(bool lock = true);
117 117
   double OMXWallTime(bool lock = true);
118 118
   double OMXMediaTime(bool fixPreroll = true, bool lock = true);
  119
+  bool OMXMediaTime(double pts, bool fixPreroll = true, bool lock = true);
119 120
   bool OMXPause(bool lock = true);
120 121
   bool OMXResume(bool lock = true);
121 122
   bool OMXUpdateClock(double pts, bool lock = true);

0 notes on commit c106cfd

arnova

This looks a bit weird. Might as well make the if above "if((g_guiSettings.GetBool("videoplayer.usedisplayasclock") && m_has_video) || !m_has_audio), right?

popcornmix

It wants the same logic as OMXSetReferenceClock, so I followed the style of that function (even though that's not how I would have written it initially).

Please sign in to comment.
Something went wrong with that request. Please try again.