Skip to content
This repository
Browse code

Merge pull request #2955 from popcornmix/ff_rew

[rtbp/omxplayer] Support ff/rew
  • Loading branch information...
commit dde99fbd7a4abceb7598f3819db9e8af5be29544 2 parents e5cd6a3 + 4fddb9a
popcornmix authored July 10, 2013
58  xbmc/cores/omxplayer/OMXPlayer.cpp
@@ -120,6 +120,11 @@
120 120
 #include "LangInfo.h"
121 121
 #include "URL.h"
122 122
 
  123
+// video not playing from clock, but stepped
  124
+#define TP(speed)  ((speed) < 0 || (speed) > 4*DVD_PLAYSPEED_NORMAL)
  125
+// audio not playing
  126
+#define TPA(speed) ((speed) != DVD_PLAYSPEED_PAUSE && (speed) != DVD_PLAYSPEED_NORMAL)
  127
+
123 128
 using namespace std;
124 129
 using namespace PVR;
125 130
 
@@ -1164,7 +1169,24 @@ void COMXPlayer::Process()
1164 1169
       m_omxPlayerAudio.GetLevel(), m_omxPlayerVideo.GetLevel(), m_omxPlayerAudio.GetDelay(), (float)m_omxPlayerAudio.GetCacheTotal());
1165 1170
     #endif
1166 1171
 
1167  
-    if (not_accepts_data && (audio_fifo_low || video_fifo_low))
  1172
+    if (TP(m_playSpeed))
  1173
+    {
  1174
+      if (m_CurrentVideo.started)
  1175
+      {
  1176
+        static double last = 0;
  1177
+        double now = m_clock.GetAbsoluteClock();
  1178
+        //if (m_av_clock.OMXIsPaused())
  1179
+        //  m_av_clock.OMXResume();
  1180
+        if (m_clock.GetAbsoluteClock() - last > 1e6/25)
  1181
+        {
  1182
+          // trickplay modes progress by stepping
  1183
+          //m_av_clock.OMXMediaTime(m_clock.GetClock());
  1184
+          m_av_clock.OMXStep();
  1185
+          last = now;
  1186
+        }
  1187
+      }
  1188
+    }
  1189
+    else if (not_accepts_data && (audio_fifo_low || video_fifo_low))
1168 1190
     {
1169 1191
       CLog::Log(LOGDEBUG, "%s - Flush! M:%.6f-%.6f (A:%.6f V:%.6f) PEF:%d%d%d S:%.2f A:%.2f V:%.2f/T:%.2f (A:%d%d V:%d%d) A:%d%% V:%d%% (%.2f,%.2f)", __FUNCTION__,
1170 1192
         stamp*1e-6, m_av_clock.OMXClockAdjustment()*1e-6, audio_pts*1e-6, video_pts*1e-6, m_av_clock.OMXIsPaused(), bOmxSentEOFs, not_accepts_data, m_playSpeed * (1.0f/DVD_PLAYSPEED_NORMAL),
@@ -2429,10 +2451,18 @@ void COMXPlayer::HandleMessages()
2429 2451
         // videoplayer just plays faster after the clock speed has been increased
2430 2452
         // 1. disable audio
2431 2453
         // 2. skip frames and adjust their pts or the clock
  2454
+
  2455
+        // when switching from trickplay to normal, we may not have a full set of reference frames
  2456
+        // in decoder and we may get corrupt frames out. Seeking to current time will avoid this.
  2457
+        if ( (speed == DVD_PLAYSPEED_PAUSE || speed == DVD_PLAYSPEED_NORMAL) &&
  2458
+             (m_playSpeed != DVD_PLAYSPEED_PAUSE && m_playSpeed != DVD_PLAYSPEED_NORMAL) )
  2459
+          m_messenger.Put(new CDVDMsgPlayerSeek(DVD_TIME_TO_MSEC(m_clock.GetClock()), (speed < 0), true, false, false, true));
  2460
+
2432 2461
         m_playSpeed = speed;
2433 2462
         m_caching = CACHESTATE_DONE;
2434 2463
         m_clock.SetSpeed(speed);
2435 2464
         m_av_clock.OMXSetSpeed(speed);
  2465
+        m_av_clock.OMXPause();
2436 2466
         m_omxPlayerAudio.SetSpeed(speed);
2437 2467
         m_omxPlayerVideo.SetSpeed(speed);
2438 2468
 
@@ -2520,12 +2550,15 @@ void COMXPlayer::HandleMessages()
2520 2550
         if(player == DVDPLAYER_VIDEO)
2521 2551
           m_CurrentVideo.started = true;
2522 2552
 
2523  
-        if ((player == DVDPLAYER_AUDIO || player == DVDPLAYER_VIDEO) && (!m_HasAudio || m_CurrentAudio.started) && (!m_HasVideo || m_CurrentVideo.started))
  2553
+        if ((player == DVDPLAYER_AUDIO || player == DVDPLAYER_VIDEO) &&
  2554
+           (TPA(m_playSpeed) || !m_HasAudio || m_CurrentAudio.started) &&
  2555
+           (!m_HasVideo || m_CurrentVideo.started))
2524 2556
         {
2525  
-          m_av_clock.OMXReset(m_HasVideo, m_HasAudio);
  2557
+          CLog::Log(LOGDEBUG, "COMXPlayer::HandleMessages - player started RESET");
  2558
+          m_av_clock.OMXReset(m_HasVideo, m_playSpeed != DVD_PLAYSPEED_NORMAL && m_playSpeed != DVD_PLAYSPEED_PAUSE ? false:m_HasAudio);
2526 2559
         }
2527 2560
 
2528  
-        CLog::Log(LOGDEBUG, "COMXPlayer::HandleMessages - player started %d", player);
  2561
+        CLog::Log(LOGDEBUG, "COMXPlayer::HandleMessages - player started %d (tpa:%d,a:%d,v:%d)", player, TPA(m_playSpeed), m_CurrentAudio.started, m_CurrentVideo.started);
2529 2562
       }
2530 2563
       else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
2531 2564
       {
@@ -2576,7 +2609,7 @@ void COMXPlayer::SetCaching(ECacheState state)
2576 2609
   || state == CACHESTATE_PVR)
2577 2610
   {
2578 2611
     m_clock.SetSpeed(DVD_PLAYSPEED_PAUSE);
2579  
-    m_av_clock.OMXSetSpeed(DVD_PLAYSPEED_PAUSE);
  2612
+    m_av_clock.OMXPause();
2580 2613
     m_omxPlayerAudio.SetSpeed(DVD_PLAYSPEED_PAUSE);
2581 2614
     m_omxPlayerAudio.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
2582 2615
     m_omxPlayerVideo.SetSpeed(DVD_PLAYSPEED_PAUSE);
@@ -2590,7 +2623,6 @@ void COMXPlayer::SetCaching(ECacheState state)
2590 2623
   ||(state == CACHESTATE_DONE && m_caching != CACHESTATE_PLAY))
2591 2624
   {
2592 2625
     m_clock.SetSpeed(m_playSpeed);
2593  
-    m_av_clock.OMXSetSpeed(m_playSpeed);
2594 2626
     m_omxPlayerAudio.SetSpeed(m_playSpeed);
2595 2627
     m_omxPlayerVideo.SetSpeed(m_playSpeed);
2596 2628
     m_pInputStream->ResetScanTimeout(0);
@@ -2600,10 +2632,6 @@ void COMXPlayer::SetCaching(ECacheState state)
2600 2632
 
2601 2633
 void COMXPlayer::SetPlaySpeed(int speed)
2602 2634
 {
2603  
-  /* only pause and normal playspeeds are allowed */
2604  
-  if(speed < 0 || speed > DVD_PLAYSPEED_NORMAL)
2605  
-    return;
2606  
-
2607 2635
   m_messenger.Put(new CDVDMsgInt(CDVDMsg::PLAYER_SETSPEED, speed));
2608 2636
   m_omxPlayerAudio.SetSpeed(speed);
2609 2637
   m_omxPlayerVideo.SetSpeed(speed);
@@ -3014,6 +3042,8 @@ int64_t COMXPlayer::GetTime()
3014 3042
     if(offset < -limit) offset = -limit;
3015 3043
   }
3016 3044
   //{CLog::Log(LOGINFO, "%s: time:%.2f stamp:%.2f dts:%d m:%d (p:%d,c:%d) =%llu", __func__, (double)m_State.time, (double)m_State.timestamp, (int)DVD_TIME_TO_MSEC(m_State.dts + m_offset_pts), (int)DVD_TIME_TO_MSEC(m_av_clock.OMXMediaTime()), (int)m_playSpeed, (int)m_caching, llrint(m_State.time + DVD_TIME_TO_MSEC(offset)));}
  3045
+  if (TP(m_playSpeed))
  3046
+    return DVD_TIME_TO_MSEC(m_clock.GetClock());
3017 3047
   return llrint(m_State.time + DVD_TIME_TO_MSEC(offset));
3018 3048
 }
3019 3049
 
@@ -3035,11 +3065,6 @@ void COMXPlayer::ToFFRW(int iSpeed)
3035 3065
   // can't rewind in menu as seeking isn't possible
3036 3066
   // forward is fine
3037 3067
   if (iSpeed < 0 && IsInMenu()) return;
3038  
-
3039  
-  /* only pause and normal playspeeds are allowed */
3040  
-  if(iSpeed > 1 || iSpeed < 0)
3041  
-    return;
3042  
-
3043 3068
   SetPlaySpeed(iSpeed * DVD_PLAYSPEED_NORMAL);
3044 3069
 }
3045 3070
 
@@ -3415,7 +3440,8 @@ void COMXPlayer::FlushBuffers(bool queued, double pts, bool accurate)
3415 3440
 
3416 3441
   CLog::Log(LOGNOTICE, "FlushBuffers: q:%d pts:%.0f a:%d", queued, pts, accurate);
3417 3442
 
3418  
-  m_av_clock.OMXStop();
  3443
+  if (!TP(m_playSpeed))
  3444
+    m_av_clock.OMXStop();
3419 3445
   m_av_clock.OMXPause();
3420 3446
 
3421 3447
   if(accurate)
7  xbmc/cores/omxplayer/OMXPlayerAudio.cpp
@@ -226,7 +226,7 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket)
226 226
   const uint8_t *data_dec = pkt->pData;
227 227
   int            data_len = pkt->iSize;
228 228
 
229  
-  if(!OMX_IS_RAW(m_format.m_dataFormat))
  229
+  if(!OMX_IS_RAW(m_format.m_dataFormat) && !bDropPacket)
230 230
   {
231 231
     while(!m_bStop && data_len > 0)
232 232
     {
@@ -283,15 +283,12 @@ bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket)
283 283
           }
284 284
         }
285 285
 
286  
-        int n = (m_nChannels * m_hints.bitspersample * m_hints.samplerate)>>3;
287  
-        if (n > 0)
288  
-          m_audioClock += ((double)decoded_size * DVD_TIME_BASE) / n;
289 286
         break;
290 287
 
291 288
       }
292 289
     }
293 290
   }
294  
-  else
  291
+  else if(!bDropPacket)
295 292
   {
296 293
     if(CodecChange())
297 294
     {
41  xbmc/linux/OMXClock.cpp
@@ -33,6 +33,7 @@
33 33
 #include "utils/MathUtils.h"
34 34
 
35 35
 #define OMX_PRE_ROLL 200
  36
+#define TP(speed) ((speed) < 0 || (speed) > 4*DVD_PLAYSPEED_NORMAL)
36 37
 
37 38
 OMXClock::OMXClock()
38 39
 {
@@ -40,7 +41,9 @@ OMXClock::OMXClock()
40 41
 
41 42
   m_fps = 25.0f;
42 43
   m_omx_speed = DVD_PLAYSPEED_NORMAL;
43  
-  m_eClock = OMX_TIME_RefClockMax;
  44
+  m_WaitMask = 0;
  45
+  m_eState = OMX_TIME_ClockStateStopped;
  46
+  m_eClock = OMX_TIME_RefClockNone;
44 47
   m_clock        = NULL;
45 48
 
46 49
   pthread_mutex_init(&m_lock, NULL);
@@ -222,6 +225,7 @@ bool  OMXClock::OMXStop(bool lock /* = true */)
222 225
       UnLock();
223 226
     return false;
224 227
   }
  228
+  m_eState = clock.eState;
225 229
 
226 230
   if(lock)
227 231
     UnLock();
@@ -256,6 +260,7 @@ bool OMXClock::OMXStep(int steps /* = 1 */, bool lock /* = true */)
256 260
   if(lock)
257 261
     UnLock();
258 262
 
  263
+  CLog::Log(LOGDEBUG, "OMXClock::Step (%d)", steps);
259 264
   return true;
260 265
 }
261 266
 
@@ -267,8 +272,6 @@ bool OMXClock::OMXReset(bool has_video, bool has_audio, bool lock /* = true */)
267 272
   if(lock)
268 273
     Lock();
269 274
 
270  
-  OMX_ERRORTYPE omx_err = OMX_ErrorNone;
271  
-
272 275
   if(!OMXSetReferenceClock(has_audio, false))
273 276
   {
274 277
     if(lock)
@@ -276,21 +279,11 @@ bool OMXClock::OMXReset(bool has_video, bool has_audio, bool lock /* = true */)
276 279
     return false;
277 280
   }
278 281
 
279  
-  OMX_TIME_CONFIG_CLOCKSTATETYPE clock;
280  
-  OMX_INIT_STRUCTURE(clock);
281  
-
282  
-  omx_err = m_omx_clock.GetConfig(OMX_IndexConfigTimeClockState, &clock);
283  
-  if(omx_err != OMX_ErrorNone)
  282
+  if (m_eState == OMX_TIME_ClockStateStopped)
284 283
   {
285  
-    CLog::Log(LOGERROR, "OMXClock::OMXReset error getting OMX_IndexConfigTimeClockState\n");
286  
-    if(lock)
287  
-      UnLock();
288  
-    return false;
289  
-  }
  284
+    OMX_TIME_CONFIG_CLOCKSTATETYPE clock;
  285
+    OMX_INIT_STRUCTURE(clock);
290 286
 
291  
-  OMX_TIME_CLOCKSTATE old_eState = clock.eState;
292  
-  if (clock.eState == OMX_TIME_ClockStateStopped)
293  
-  {
294 287
     clock.eState    = OMX_TIME_ClockStateWaitingForStartTime;
295 288
     clock.nOffset   = ToOMXTime(-1000LL * OMX_PRE_ROLL);
296 289
 
@@ -298,7 +291,7 @@ bool OMXClock::OMXReset(bool has_video, bool has_audio, bool lock /* = true */)
298 291
 
299 292
     if(clock.nWaitMask)
300 293
     {
301  
-      omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeClockState, &clock);
  294
+      OMX_ERRORTYPE omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeClockState, &clock);
302 295
       if(omx_err != OMX_ErrorNone)
303 296
       {
304 297
         CLog::Log(LOGERROR, "OMXClock::OMXReset error setting OMX_IndexConfigTimeClockState\n");
@@ -306,10 +299,13 @@ bool OMXClock::OMXReset(bool has_video, bool has_audio, bool lock /* = true */)
306 299
           UnLock();
307 300
         return false;
308 301
       }
  302
+      CLog::Log(LOGDEBUG, "OMXClock::OMXReset audio / video : %d / %d wait mask %d->%d state : %d->%d\n",
  303
+          has_audio, has_video, m_WaitMask, clock.nWaitMask, m_eState, clock.eState);
  304
+      if (m_eState != OMX_TIME_ClockStateStopped)
  305
+        m_WaitMask = clock.nWaitMask;
  306
+      m_eState = clock.eState;
309 307
     }
310 308
   }
311  
-  CLog::Log(LOGDEBUG, "OMXClock::OMXReset audio / video : %d / %d wait mask %d state : %d->%d\n",
312  
-      has_audio, has_video, clock.nWaitMask, old_eState, clock.eState);
313 309
 
314 310
   if(lock)
315 311
     UnLock();
@@ -453,7 +449,7 @@ bool OMXClock::OMXResume(bool lock /* = true */)
453 449
     if(lock)
454 450
       Lock();
455 451
 
456  
-    if (OMXSetSpeed(DVD_PLAYSPEED_NORMAL, false, true))
  452
+    if (OMXSetSpeed(m_omx_speed, false, true))
457 453
       m_pause = false;
458 454
 
459 455
     if(lock)
@@ -478,7 +474,10 @@ bool OMXClock::OMXSetSpeed(int speed, bool lock /* = true */, bool pause_resume
478 474
     OMX_TIME_CONFIG_SCALETYPE scaleType;
479 475
     OMX_INIT_STRUCTURE(scaleType);
480 476
 
481  
-    scaleType.xScale = (speed << 16) / DVD_PLAYSPEED_NORMAL;
  477
+    if (TP(speed))
  478
+      scaleType.xScale = 0; // for trickplay we just pause, and single step
  479
+    else
  480
+      scaleType.xScale = (speed << 16) / DVD_PLAYSPEED_NORMAL;
482 481
     omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeScale, &scaleType);
483 482
     if(omx_err != OMX_ErrorNone)
484 483
     {
2  xbmc/linux/OMXClock.h
@@ -52,6 +52,8 @@ class OMXClock
52 52
   pthread_mutex_t   m_lock;
53 53
   double            m_fps;
54 54
   int               m_omx_speed;
  55
+  OMX_U32           m_WaitMask;
  56
+  OMX_TIME_CLOCKSTATE   m_eState;
55 57
   OMX_TIME_REFCLOCKTYPE m_eClock;
56 58
   CDVDClock         *m_clock;
57 59
 private:

0 notes on commit dde99fb

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