Skip to content
This repository
Browse code

Merge pull request #2372 from huceke/raspberrypi

[rbp/omxplayer] sync up with dvdplayer master changes
  • Loading branch information...
commit 3caf659ddb92c83c2cc825a32126bc192651a233 2 parents 4e8a5a0 + 28de0da
huceke authored April 03, 2013
295  xbmc/cores/omxplayer/OMXPlayer.cpp
@@ -38,6 +38,7 @@
38 38
 #include "filesystem/SpecialProtocol.h"
39 39
 #include "guilib/GUIWindowManager.h"
40 40
 #include "settings/AdvancedSettings.h"
  41
+#include "settings/MediaSettings.h"
41 42
 #include "settings/GUISettings.h"
42 43
 #include "settings/Settings.h"
43 44
 #include "threads/SingleLock.h"
@@ -424,9 +425,11 @@ COMXPlayer::COMXPlayer(IPlayerCallback &callback)
424 425
   m_UpdateApplication = 0;
425 426
   m_caching           = CACHESTATE_DONE;
426 427
   m_playSpeed         = DVD_PLAYSPEED_NORMAL;
  428
+  m_HasVideo          = false;
  429
+  m_HasAudio          = false;
427 430
 
428  
-  m_State.Clear();
429 431
   m_dvd.Clear();
  432
+  m_State.Clear();
430 433
   m_EdlAutoSkipMarkers.Clear();
431 434
 
432 435
   memset(&m_SpeedState, 0, sizeof(m_SpeedState));
@@ -483,7 +486,6 @@ bool COMXPlayer::OpenFile(const CFileItem &file, const CPlayerOptions &options)
483 486
     g_renderManager.PreInit();
484 487
 
485 488
     Create();
486  
-
487 489
     if(!m_ready.WaitMSec(100))
488 490
     {
489 491
       CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
@@ -538,6 +540,9 @@ bool COMXPlayer::CloseFile()
538 540
   m_Edl.Clear();
539 541
   m_EdlAutoSkipMarkers.Clear();
540 542
 
  543
+  m_HasVideo = false;
  544
+  m_HasAudio = false;
  545
+
541 546
   g_renderManager.UnInit();
542 547
   return true;
543 548
 }
@@ -571,7 +576,7 @@ bool COMXPlayer::OpenInputStream()
571 576
   {
572 577
     m_filename = g_mediaManager.TranslateDevicePath("");
573 578
   }
574  
-retry:
  579
+
575 580
   // before creating the input stream, if this is an HLS playlist then get the
576 581
   // most appropriate bitrate based on our network settings
577 582
   if (filename.Left(7) == "http://" && filename.Right(5) == ".m3u8")
@@ -603,7 +608,6 @@ bool COMXPlayer::OpenInputStream()
603 608
                        || m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY) ) )
604 609
   {
605 610
     CLog::Log(LOGINFO, "COMXPlayer::OpenInputStream - DVD/BD not supported - Will try...");
606  
-    // return false;
607 611
   }
608 612
 
609 613
   // find any available external subtitles for non dvd files
@@ -637,7 +641,7 @@ bool COMXPlayer::OpenInputStream()
637 641
           AddSubtitleFile(filenames[i]);
638 642
         }
639 643
       }
640  
-    } // end loop over all subtitle files    
  644
+    } // end loop over all subtitle files
641 645
 
642 646
     CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleCached = true;
643 647
   }
@@ -645,7 +649,6 @@ bool COMXPlayer::OpenInputStream()
645 649
   SetAVDelay(CMediaSettings::Get().GetCurrentVideoSettings().m_AudioDelay);
646 650
   SetSubTitleDelay(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleDelay);
647 651
   m_av_clock.Reset();
648  
-  //m_av_clock.OMXReset();
649 652
   m_dvd.Clear();
650 653
   m_iChannelEntryTimeOut = 0;
651 654
 
@@ -704,8 +707,9 @@ bool COMXPlayer::OpenDemuxStream()
704 707
 
705 708
 void COMXPlayer::OpenDefaultStreams(bool reset)
706 709
 {
707  
-  // bypass for DVDs. The DVD Navigator has already dictated which streams to open.
708  
-  if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
  710
+  // if input stream dictate, we will open later
  711
+  if(m_dvd.iSelectedAudioStream >= 0
  712
+  || m_dvd.iSelectedSPUStream   >= 0)
709 713
     return;
710 714
 
711 715
   OMXSelectionStreams streams;
@@ -756,20 +760,15 @@ void COMXPlayer::OpenDefaultStreams(bool reset)
756 760
     CloseSubtitleStream(true);
757 761
 
758 762
   // open teletext stream
759  
-  /*
760 763
   streams = m_SelectionStreams.Get(STREAM_TELETEXT);
761 764
   valid   = false;
762  
-  for(SelectionStreams::iterator it = streams.begin(); it != streams.end() && !valid; ++it)
  765
+  for(OMXSelectionStreams::iterator it = streams.begin(); it != streams.end() && !valid; ++it)
763 766
   {
764 767
     if(OpenTeletextStream(it->id, it->source))
765 768
       valid = true;
766 769
   }
767 770
   if(!valid)
768 771
     CloseTeletextStream(true);
769  
-  */
770  
-
771  
-  //m_av_clock.OMXStop();
772  
-  //m_av_clock.OMXReset();
773 772
 }
774 773
 
775 774
 bool COMXPlayer::ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream)
@@ -891,6 +890,9 @@ bool COMXPlayer::IsBetterStream(COMXCurrentStream& current, CDemuxStream* stream
891 890
   if(m_PlayerOptions.video_only && current.type != STREAM_VIDEO)
892 891
     return false;
893 892
 
  893
+  if(stream->disabled)
  894
+    return false;
  895
+
894 896
   if (m_pInputStream && ( m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)
895 897
                        || m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY) ) )
896 898
   {
@@ -920,9 +922,6 @@ bool COMXPlayer::IsBetterStream(COMXCurrentStream& current, CDemuxStream* stream
920 922
     && stream->iId    == current.id)
921 923
       return false;
922 924
 
923  
-    if(stream->disabled)
924  
-      return false;
925  
-
926 925
     if(stream->type != current.type)
927 926
       return false;
928 927
 
@@ -940,21 +939,21 @@ void COMXPlayer::Process()
940 939
   bool bOmxWaitVideo = false;
941 940
   bool bOmxWaitAudio = false;
942 941
 
943  
-  if(!OpenInputStream())
  942
+  if (!OpenInputStream())
944 943
   {
945 944
     m_bAbortRequest = true;
946 945
     return;
947 946
   }
948 947
 
949  
-  if(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
  948
+  if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
950 949
   {
951  
-    CLog::Log(LOGNOTICE, "OMXPlayer: playing a dvd with menu's");
  950
+    CLog::Log(LOGNOTICE, "OMXPlayer: playing a file with menu's");
952 951
     m_PlayerOptions.starttime = 0;
953 952
 
954 953
     if(m_PlayerOptions.state.size() > 0)
955  
-      ((CDVDInputStreamNavigator*)m_pInputStream)->SetNavigatorState(m_PlayerOptions.state);
956  
-    else
957  
-      ((CDVDInputStreamNavigator*)m_pInputStream)->EnableSubtitleStream(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn);
  954
+      ptr->SetState(m_PlayerOptions.state);
  955
+    else if(CDVDInputStreamNavigator* nav = dynamic_cast<CDVDInputStreamNavigator*>(m_pInputStream))
  956
+      nav->EnableSubtitleStream(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn);
958 957
 
959 958
     CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleCached = true;
960 959
   }
@@ -1098,6 +1097,10 @@ void COMXPlayer::Process()
1098 1097
 
1099 1098
       OpenDefaultStreams();
1100 1099
 
  1100
+      // never allow first frames after open to be skipped
  1101
+      if( m_player_video.IsInited() )
  1102
+        m_player_video.SendMessage(new CDVDMsg(CDVDMsg::VIDEO_NOSKIP));
  1103
+
1101 1104
       if (CachePVRStream())
1102 1105
         SetCaching(CACHESTATE_PVR);
1103 1106
 
@@ -1154,10 +1157,8 @@ void COMXPlayer::Process()
1154 1157
         continue;
1155 1158
 
1156 1159
       // check for a still frame state
1157  
-      if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
  1160
+      if (CDVDInputStream::IMenus* pStream = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
1158 1161
       {
1159  
-        CDVDInputStreamNavigator* pStream = static_cast<CDVDInputStreamNavigator*>(m_pInputStream);
1160  
-
1161 1162
         // stills will be skipped
1162 1163
         if(m_dvd.state == DVDSTATE_STILL)
1163 1164
         {
@@ -1328,7 +1329,7 @@ void COMXPlayer::ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket)
1328 1329
 
1329 1330
 void COMXPlayer::ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket)
1330 1331
 {
1331  
-  if (m_CurrentAudio.stream != (void*)pStream
  1332
+  if (m_CurrentAudio.stream  != (void*)pStream
1332 1333
   ||  m_CurrentAudio.changes != pStream->changes)
1333 1334
   {
1334 1335
     /* check so that dmuxer hints or extra data hasn't changed */
@@ -1594,6 +1595,7 @@ void COMXPlayer::HandlePlaySpeed()
1594 1595
   if(m_caching != caching)
1595 1596
     SetCaching(caching);
1596 1597
 
  1598
+
1597 1599
   if(GetPlaySpeed() != DVD_PLAYSPEED_NORMAL && GetPlaySpeed() != DVD_PLAYSPEED_PAUSE)
1598 1600
   {
1599 1601
     if (IsInMenu())
@@ -1769,6 +1771,24 @@ void COMXPlayer::UpdateTimestamps(COMXCurrentStream& current, DemuxPacket* pPack
1769 1771
     current.dur = 0.1 * (current.dur * 9 + (dts - current.dts));
1770 1772
 
1771 1773
   current.dts = dts;
  1774
+
  1775
+  /* send a playback state structure periodically */
  1776
+  if(current.dts_state == DVD_NOPTS_VALUE
  1777
+  || abs(current.dts - current.dts_state) > DVD_MSEC_TO_TIME(200))
  1778
+  {
  1779
+    current.dts_state = current.dts;
  1780
+    if (current.inited)
  1781
+    {
  1782
+      // make sure we send no outdated state to a/v players
  1783
+      UpdatePlayState(0);
  1784
+      SendPlayerMessage(new CDVDMsgType<SPlayerState>(CDVDMsg::PLAYER_DISPLAYTIME, m_StateInput), current.player);
  1785
+    }
  1786
+    else
  1787
+    {
  1788
+      CSingleLock lock(m_StateSection);
  1789
+      m_State = m_StateInput;
  1790
+    }
  1791
+  }
1772 1792
 }
1773 1793
 
1774 1794
 void COMXPlayer::UpdateLimits(double& minimum, double& maximum, double dts)
@@ -2079,6 +2099,11 @@ void COMXPlayer::HandleMessages()
2079 2099
         double start = DVD_NOPTS_VALUE;
2080 2100
 
2081 2101
         int time = msg.GetRestore() ? (int)m_Edl.RestoreCutTime(msg.GetTime()) : msg.GetTime();
  2102
+
  2103
+        // if input streams doesn't support seektime we must convert back to clock
  2104
+        if(dynamic_cast<CDVDInputStream::ISeekTime*>(m_pInputStream) == NULL)
  2105
+          time -= DVD_TIME_TO_MSEC(m_State.time_offset - m_offset_pts);
  2106
+
2082 2107
         CLog::Log(LOGDEBUG, "demuxer seek to: %d", time);
2083 2108
         if (m_pDemuxer && m_pDemuxer->SeekTime(time, msg.GetBackward(), &start))
2084 2109
         {
@@ -2088,6 +2113,9 @@ void COMXPlayer::HandleMessages()
2088 2113
             if(!m_pSubtitleDemuxer->SeekTime(time, msg.GetBackward()))
2089 2114
               CLog::Log(LOGDEBUG, "failed to seek subtitle demuxer: %d, success", time);
2090 2115
           }
  2116
+          // dts after successful seek
  2117
+          m_StateInput.dts = start;
  2118
+
2091 2119
           FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate());
2092 2120
         }
2093 2121
         else
@@ -2145,7 +2173,6 @@ void COMXPlayer::HandleMessages()
2145 2173
             {
2146 2174
               m_dvd.iSelectedAudioStream = -1;
2147 2175
               CloseAudioStream(false);
2148  
-              // TODO : check //CloseVideoStream(false);
2149 2176
               m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true, true, true));
2150 2177
             }
2151 2178
           }
@@ -2196,13 +2223,14 @@ void COMXPlayer::HandleMessages()
2196 2223
 
2197 2224
         CDVDMsgPlayerSetState* pMsgPlayerSetState = (CDVDMsgPlayerSetState*)pMsg;
2198 2225
 
2199  
-        if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
  2226
+        if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
2200 2227
         {
2201  
-          std::string s = pMsgPlayerSetState->GetState();
2202  
-          ((CDVDInputStreamNavigator*)m_pInputStream)->SetNavigatorState(s);
2203  
-          m_dvd.state = DVDSTATE_NORMAL;
2204  
-          m_dvd.iDVDStillStartTime = 0;
2205  
-          m_dvd.iDVDStillTime = 0;
  2228
+          if(ptr->SetState(pMsgPlayerSetState->GetState()))
  2229
+          {
  2230
+            m_dvd.state = DVDSTATE_NORMAL;
  2231
+            m_dvd.iDVDStillStartTime = 0;
  2232
+            m_dvd.iDVDStillTime = 0;
  2233
+          }
2206 2234
         }
2207 2235
 
2208 2236
         g_infoManager.SetDisplayAfterSeek();
@@ -2340,6 +2368,24 @@ void COMXPlayer::HandleMessages()
2340 2368
           m_CurrentVideo.started = true;
2341 2369
         CLog::Log(LOGDEBUG, "COMXPlayer::HandleMessages - player started %d", player);
2342 2370
       }
  2371
+      else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
  2372
+      {
  2373
+        COMXPlayer::SPlayerState& state = ((CDVDMsgType<COMXPlayer::SPlayerState>*)pMsg)->m_value;
  2374
+
  2375
+        CSingleLock lock(m_StateSection);
  2376
+        /* prioritize data from video player, but only accept data        *
  2377
+         * after it has been started to avoid race conditions after seeks */
  2378
+        if(m_CurrentVideo.started)
  2379
+        {
  2380
+          if(state.player == DVDPLAYER_VIDEO)
  2381
+            m_State = state;
  2382
+        }
  2383
+        else if(m_CurrentAudio.started)
  2384
+        {
  2385
+          if(state.player == DVDPLAYER_AUDIO)
  2386
+            m_State = state;
  2387
+        }
  2388
+      }
2343 2389
     }
2344 2390
     catch (...)
2345 2391
     {
@@ -2348,6 +2394,7 @@ void COMXPlayer::HandleMessages()
2348 2394
 
2349 2395
     pMsg->Release();
2350 2396
   }
  2397
+
2351 2398
 }
2352 2399
 
2353 2400
 void COMXPlayer::SetCaching(ECacheState state)
@@ -2440,14 +2487,12 @@ bool COMXPlayer::IsPaused() const
2440 2487
 
2441 2488
 bool COMXPlayer::HasVideo() const
2442 2489
 {
2443  
-  if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) return true;
2444  
-
2445  
-  return m_SelectionStreams.Count(STREAM_VIDEO) > 0 ? true : false;
  2490
+  return m_HasVideo;
2446 2491
 }
2447 2492
 
2448 2493
 bool COMXPlayer::HasAudio() const
2449 2494
 {
2450  
-  return m_SelectionStreams.Count(STREAM_AUDIO) > 0 ? true : false;
  2495
+  return m_HasAudio;
2451 2496
 }
2452 2497
 
2453 2498
 bool COMXPlayer::IsPassthrough() const
@@ -2589,17 +2634,17 @@ bool COMXPlayer::SeekScene(bool bPlus)
2589 2634
 void COMXPlayer::GetAudioInfo(CStdString &strAudioInfo)
2590 2635
 {
2591 2636
   { CSingleLock lock(m_StateSection);
2592  
-    strAudioInfo.Format("D(%s)", m_State.demux_audio.c_str());
  2637
+    strAudioInfo.Format("D(%s)", m_StateInput.demux_audio.c_str());
2593 2638
   }
2594  
-  strAudioInfo.AppendFormat(" P(%s)", m_player_audio.GetPlayerInfo().c_str());
  2639
+  strAudioInfo.AppendFormat("\nP(%s)", m_player_audio.GetPlayerInfo().c_str());
2595 2640
 }
2596 2641
 
2597 2642
 void COMXPlayer::GetVideoInfo(CStdString &strVideoInfo)
2598 2643
 {
2599 2644
   { CSingleLock lock(m_StateSection);
2600  
-    strVideoInfo.Format("D(%s)", m_State.demux_video.c_str());
  2645
+    strVideoInfo.Format("D(%s)", m_StateInput.demux_video.c_str());
2601 2646
   }
2602  
-  strVideoInfo.AppendFormat(" P(%s)", m_player_video.GetPlayerInfo().c_str());
  2647
+  strVideoInfo.AppendFormat("\nP(%s)", m_player_video.GetPlayerInfo().c_str());
2603 2648
 }
2604 2649
 
2605 2650
 void COMXPlayer::GetGeneralInfo(CStdString& strGeneralInfo)
@@ -2620,7 +2665,7 @@ void COMXPlayer::GetGeneralInfo(CStdString& strGeneralInfo)
2620 2665
 
2621 2666
     CStdString strBuf;
2622 2667
     CSingleLock lock(m_StateSection);
2623  
-    if(m_State.cache_bytes >= 0)
  2668
+    if(m_StateInput.cache_bytes >= 0)
2624 2669
     {
2625 2670
       strBuf.AppendFormat(" cache:%s %2.0f%%"
2626 2671
                          , StringUtils::SizeToString(m_State.cache_bytes).c_str()
@@ -2666,7 +2711,7 @@ float COMXPlayer::GetPercentage()
2666 2711
 float COMXPlayer::GetCachePercentage()
2667 2712
 {
2668 2713
   CSingleLock lock(m_StateSection);
2669  
-  return m_State.cache_offset * 100; // NOTE: Percentage returned is relative
  2714
+  return m_StateInput.cache_offset * 100; // NOTE: Percentage returned is relative
2670 2715
 }
2671 2716
 
2672 2717
 void COMXPlayer::SetAVDelay(float fValue)
@@ -2689,6 +2734,7 @@ float COMXPlayer::GetSubTitleDelay()
2689 2734
   return -m_player_video.GetSubtitleDelay() / DVD_TIME_BASE;
2690 2735
 }
2691 2736
 
  2737
+// priority: 1: libdvdnav, 2: external subtitles, 3: muxed subtitles
2692 2738
 int COMXPlayer::GetSubtitleCount()
2693 2739
 {
2694 2740
   OMXStreamLock lock(this);
@@ -2752,7 +2798,7 @@ int COMXPlayer::GetAudioStream()
2752 2798
 {
2753 2799
   return m_SelectionStreams.IndexOf(STREAM_AUDIO, *this);
2754 2800
 }
2755  
- 
  2801
+
2756 2802
 void COMXPlayer::SetAudioStream(int iStream)
2757 2803
 {
2758 2804
   m_messenger.Put(new CDVDMsgPlayerSetAudioStream(iStream));
@@ -2788,12 +2834,13 @@ int64_t COMXPlayer::GetTime()
2788 2834
 {
2789 2835
   CSingleLock lock(m_StateSection);
2790 2836
   double offset = 0;
  2837
+  const double limit  = DVD_MSEC_TO_TIME(200);
2791 2838
   if(m_State.timestamp > 0)
2792 2839
   {
2793 2840
     offset  = m_av_clock.GetAbsoluteClock() - m_State.timestamp;
2794 2841
     offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL;
2795  
-    if(offset >  1000) offset =  1000;
2796  
-    if(offset < -1000) offset = -1000;
  2842
+    if(offset >  limit) offset =  limit;
  2843
+    if(offset < -limit) offset = -limit;
2797 2844
   }
2798 2845
   return llrint(m_State.time + DVD_TIME_TO_MSEC(offset));
2799 2846
 }
@@ -2874,6 +2921,7 @@ bool COMXPlayer::OpenAudioStream(int iStream, int source, bool reset)
2874 2921
   m_CurrentAudio.hint = hint;
2875 2922
   m_CurrentAudio.stream = (void*)pStream;
2876 2923
   m_CurrentAudio.started = false;
  2924
+  m_HasAudio = true;
2877 2925
 
2878 2926
   /* we are potentially going to be waiting on this */
2879 2927
   m_player_audio.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
@@ -2928,7 +2976,7 @@ bool COMXPlayer::OpenVideoStream(int iStream, int source, bool reset)
2928 2976
   if(m_CurrentVideo.id    < 0
2929 2977
   || m_CurrentVideo.hint != hint)
2930 2978
   {
2931  
-    if(!m_player_video.OpenStream(hint))
  2979
+    if (!m_player_video.OpenStream(hint))
2932 2980
     {
2933 2981
       /* mark stream as disabled, to disallaw further attempts */
2934 2982
       CLog::Log(LOGWARNING, "%s - Unsupported stream %d. Stream disabled.", __FUNCTION__, iStream);
@@ -2955,6 +3003,7 @@ bool COMXPlayer::OpenVideoStream(int iStream, int source, bool reset)
2955 3003
   m_CurrentVideo.hint = hint;
2956 3004
   m_CurrentVideo.stream = (void*)pStream;
2957 3005
   m_CurrentVideo.started = false;
  3006
+  m_HasVideo = true;
2958 3007
 
2959 3008
   /* we are potentially going to be waiting on this */
2960 3009
   m_player_video.SendMessage(new CDVDMsg(CDVDMsg::PLAYER_STARTED), 1);
@@ -3241,6 +3290,11 @@ void COMXPlayer::FlushBuffers(bool queued, double pts, bool accurate)
3241 3290
     if(pts != DVD_NOPTS_VALUE)
3242 3291
       m_av_clock.Discontinuity(pts);
3243 3292
     UpdatePlayState(0);
  3293
+
  3294
+    // update state, buffers are flushed and it may take some time until
  3295
+    // we get an update from players
  3296
+    CSingleLock lock(m_StateSection);
  3297
+    m_State = m_StateInput;
3244 3298
   }
3245 3299
 }
3246 3300
 
@@ -3259,6 +3313,29 @@ int COMXPlayer::OnDVDNavResult(void* pData, int iMessage)
3259 3313
       m_dvd.iSelectedSPUStream   = *(int*)pData;
3260 3314
     else if(iMessage == 4)
3261 3315
       m_player_video.EnableSubtitle(*(int*)pData ? true: false);
  3316
+    else if(iMessage == 5)
  3317
+    {
  3318
+      if (m_dvd.state != DVDSTATE_STILL)
  3319
+      {
  3320
+        // else notify the player we have received a still frame
  3321
+
  3322
+        m_dvd.iDVDStillTime      = *(int*)pData;
  3323
+        m_dvd.iDVDStillStartTime = XbmcThreads::SystemClockMillis();
  3324
+
  3325
+        /* adjust for the output delay in the video queue */
  3326
+        unsigned int time = 0;
  3327
+        if( m_CurrentVideo.stream && m_dvd.iDVDStillTime > 0 )
  3328
+        {
  3329
+          time = (unsigned int)(m_player_video.GetOutputDelay() / ( DVD_TIME_BASE / 1000 ));
  3330
+          if( time < 10000 && time > 0 )
  3331
+            m_dvd.iDVDStillTime += time;
  3332
+        }
  3333
+        m_dvd.state = DVDSTATE_STILL;
  3334
+        CLog::Log(LOGDEBUG,
  3335
+                  "DVDNAV_STILL_FRAME - waiting %i sec, with delay of %d sec",
  3336
+                  m_dvd.iDVDStillTime, time / 1000);
  3337
+      }
  3338
+    }
3262 3339
 
3263 3340
     return 0;
3264 3341
   }
@@ -3497,11 +3574,12 @@ bool COMXPlayer::OnAction(const CAction &action)
3497 3574
         pMenus->OnMenu();
3498 3575
         // send a message to everyone that we've gone to the menu
3499 3576
         CGUIMessage msg(GUI_MSG_VIDEO_MENU_STARTED, 0, 0);
3500  
-        g_windowManager.SendMessage(msg);
  3577
+        g_windowManager.SendThreadMessage(msg);
3501 3578
         return true;
3502 3579
       }
3503 3580
       break;
3504 3581
     }
  3582
+
3505 3583
     if (pMenus->IsInMenu())
3506 3584
     {
3507 3585
       switch (action.GetID())
@@ -3774,7 +3852,7 @@ int COMXPlayer::AddSubtitle(const CStdString& strSubPath)
3774 3852
 int COMXPlayer::GetCacheLevel() const
3775 3853
 {
3776 3854
   CSingleLock lock(m_StateSection);
3777  
-  return (int)(m_State.cache_level * 100);
  3855
+  return (int)(m_StateInput.cache_level * 100);
3778 3856
 }
3779 3857
 
3780 3858
 double COMXPlayer::GetQueueTime()
@@ -3784,6 +3862,26 @@ double COMXPlayer::GetQueueTime()
3784 3862
   return max(a, v) * 8000.0 / 100;
3785 3863
 }
3786 3864
 
  3865
+void COMXPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info)
  3866
+{
  3867
+  info.bitrate = m_player_video.GetVideoBitrate();
  3868
+
  3869
+  CStdString retVal;
  3870
+  if (m_pDemuxer && (m_CurrentVideo.id != -1))
  3871
+    m_pDemuxer->GetStreamCodecName(m_CurrentVideo.id, retVal);
  3872
+  info.videoCodecName = retVal;
  3873
+  info.videoAspectRatio = g_renderManager.GetAspectRatio();
  3874
+  g_renderManager.GetVideoRect(info.SrcRect, info.DestRect);
  3875
+}
  3876
+
  3877
+int COMXPlayer::GetSourceBitrate()
  3878
+{
  3879
+  if (m_pInputStream)
  3880
+    return (int)m_pInputStream->GetBitstreamStats().GetBitrate();
  3881
+
  3882
+  return 0;
  3883
+}
  3884
+
3787 3885
 void COMXPlayer::GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info)
3788 3886
 {
3789 3887
   if (index < 0 || index > GetAudioStreamCount() - 1)
@@ -3817,26 +3915,6 @@ void COMXPlayer::GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info)
3817 3915
   }
3818 3916
 }
3819 3917
 
3820  
-void COMXPlayer::GetVideoStreamInfo(SPlayerVideoStreamInfo &info)
3821  
-{
3822  
-  info.bitrate = m_player_video.GetVideoBitrate();
3823  
-
3824  
-  CStdString retVal;
3825  
-  if (m_pDemuxer && (m_CurrentVideo.id != -1))
3826  
-    m_pDemuxer->GetStreamCodecName(m_CurrentVideo.id, retVal);
3827  
-  info.videoCodecName = retVal;
3828  
-  info.videoAspectRatio = g_renderManager.GetAspectRatio();
3829  
-  g_renderManager.GetVideoRect(info.SrcRect, info.DestRect);
3830  
-}
3831  
-
3832  
-int COMXPlayer::GetSourceBitrate()
3833  
-{
3834  
-  if (m_pInputStream)
3835  
-    return (int)m_pInputStream->GetBitstreamStats().GetBitrate();
3836  
-
3837  
-  return 0;
3838  
-}
3839  
-
3840 3918
 int COMXPlayer::AddSubtitleFile(const std::string& filename, const std::string& subfilename, CDemuxStream::EFlags flags)
3841 3919
 {
3842 3920
   std::string ext = URIUtils::GetExtension(filename);
@@ -3874,18 +3952,16 @@ int COMXPlayer::AddSubtitleFile(const std::string& filename, const std::string&
3874 3952
 
3875 3953
 void COMXPlayer::UpdatePlayState(double timeout)
3876 3954
 {
3877  
-  if(m_State.timestamp != 0
3878  
-  && m_State.timestamp + DVD_MSEC_TO_TIME(timeout) > m_av_clock.GetAbsoluteClock())
  3955
+  if(m_StateInput.timestamp != 0
  3956
+  && m_StateInput.timestamp + DVD_MSEC_TO_TIME(timeout) > m_av_clock.GetAbsoluteClock())
3879 3957
     return;
3880 3958
 
3881  
-  SPlayerState state(m_State);
  3959
+  SPlayerState state(m_StateInput);
3882 3960
 
3883 3961
   if     (m_CurrentVideo.dts != DVD_NOPTS_VALUE)
3884 3962
     state.dts = m_CurrentVideo.dts;
3885 3963
   else if(m_CurrentAudio.dts != DVD_NOPTS_VALUE)
3886 3964
     state.dts = m_CurrentAudio.dts;
3887  
-  else
3888  
-    state.dts = m_av_clock.GetClock();
3889 3965
 
3890 3966
   if(m_pDemuxer)
3891 3967
   {
@@ -3893,15 +3969,21 @@ void COMXPlayer::UpdatePlayState(double timeout)
3893 3969
     state.chapter_count = m_pDemuxer->GetChapterCount();
3894 3970
     m_pDemuxer->GetChapterName(state.chapter_name);
3895 3971
 
3896  
-    // TODO : workaround until omx clock handling is rewritten
3897  
-    if(m_playSpeed == DVD_PLAYSPEED_NORMAL)
3898  
-      state.time       = DVD_TIME_TO_MSEC(m_av_clock.OMXMediaTime(true, true));
3899  
-    else
3900  
-      state.time       = DVD_TIME_TO_MSEC(m_av_clock.GetClock() + m_offset_pts);
  3972
+    if(state.dts == DVD_NOPTS_VALUE)
  3973
+      state.time     = 0;
  3974
+    else 
  3975
+      // TODO : workaround until omx clock handling is rewritten
  3976
+      if(m_playSpeed == DVD_PLAYSPEED_NORMAL)
  3977
+        state.time     = DVD_TIME_TO_MSEC(m_av_clock.OMXMediaTime(true, true));
  3978
+      else
  3979
+        state.time     = DVD_TIME_TO_MSEC(state.dts + m_offset_pts);
3901 3980
     state.time_total = m_pDemuxer->GetStreamLength();
3902  
-
  3981
+    state.time_src   = ETIMESOURCE_CLOCK;
3903 3982
   }
3904 3983
 
  3984
+  state.canpause     = true;
  3985
+  state.canseek      = true;
  3986
+
3905 3987
   if(m_pInputStream)
3906 3988
   {
3907 3989
     // override from input stream if needed
@@ -3917,27 +3999,26 @@ void COMXPlayer::UpdatePlayState(double timeout)
3917 3999
     {
3918 4000
       state.time       = pDisplayTime->GetTime();
3919 4001
       state.time_total = pDisplayTime->GetTotalTime();
  4002
+      state.time_src   = ETIMESOURCE_INPUT;
3920 4003
     }
3921 4004
 
3922  
-    if (dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
  4005
+    if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
3923 4006
     {
  4007
+      if(!ptr->GetState(state.player_state))
  4008
+        state.player_state = "";
  4009
+
3924 4010
       if(m_dvd.state == DVDSTATE_STILL)
3925 4011
       {
3926 4012
         state.time       = XbmcThreads::SystemClockMillis() - m_dvd.iDVDStillStartTime;
3927 4013
         state.time_total = m_dvd.iDVDStillTime;
  4014
+        state.time_src   = ETIMESOURCE_MENU;
3928 4015
       }
3929 4016
     }
3930 4017
 
3931  
-    if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER))
3932  
-    {
3933  
-      CDVDInputStreamPVRManager* pvrinputstream = static_cast<CDVDInputStreamPVRManager*>(m_pInputStream);
3934  
-      state.canpause = pvrinputstream->CanPause();
3935  
-      state.canseek  = pvrinputstream->CanSeek();
3936  
-    }
3937  
-    else
  4018
+    if (CDVDInputStream::ISeekable* ptr = dynamic_cast<CDVDInputStream::ISeekable*>(m_pInputStream))
3938 4019
     {
3939  
-      state.canseek  = state.time_total > 0 ? true : false;
3940  
-      state.canpause = true;
  4020
+      state.canpause = ptr->CanPause();
  4021
+      state.canseek  = ptr->CanSeek();
3941 4022
     }
3942 4023
   }
3943 4024
 
@@ -3947,15 +4028,13 @@ void COMXPlayer::UpdatePlayState(double timeout)
3947 4028
     state.time_total  = m_Edl.RemoveCutTime(llrint(state.time_total));
3948 4029
   }
3949 4030
 
3950  
-  state.player_state = "";
3951  
-  if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
3952  
-  {
  4031
+  if(state.time_total <= 0)
  4032
+    state.canseek  = false;
  4033
+
  4034
+  if (state.time_src == ETIMESOURCE_CLOCK)
  4035
+    state.time_offset = m_offset_pts;
  4036
+  else if (state.dts != DVD_NOPTS_VALUE)
3953 4037
     state.time_offset = DVD_MSEC_TO_TIME(state.time) - state.dts;
3954  
-    if(!((CDVDInputStreamNavigator*)m_pInputStream)->GetNavigatorState(state.player_state))
3955  
-      state.player_state = "";
3956  
-  }
3957  
-  else
3958  
-    state.time_offset = 0;
3959 4038
 
3960 4039
   if (m_CurrentAudio.id >= 0 && m_pDemuxer)
3961 4040
   {
@@ -4002,7 +4081,7 @@ void COMXPlayer::UpdatePlayState(double timeout)
4002 4081
   state.timestamp = m_av_clock.GetAbsoluteClock();
4003 4082
 
4004 4083
   CSingleLock lock(m_StateSection);
4005  
-  m_State = state;
  4084
+  m_StateInput = state;
4006 4085
 }
4007 4086
 
4008 4087
 void COMXPlayer::UpdateApplication(double timeout)
@@ -4073,11 +4152,21 @@ bool COMXPlayer::GetStreamDetails(CStreamDetails &details)
4073 4152
 {
4074 4153
   if (m_pDemuxer)
4075 4154
   {
4076  
-    bool result=CDVDFileInfo::DemuxerToStreamDetails(m_pInputStream, m_pDemuxer, details);
  4155
+    bool result = CDVDFileInfo::DemuxerToStreamDetails(m_pInputStream, m_pDemuxer, details);
4077 4156
     if (result && details.GetStreamCount(CStreamDetail::VIDEO) > 0) // this is more correct (dvds in particular)
4078 4157
     {
4079  
-      ((CStreamDetailVideo*)details.GetNthStream(CStreamDetail::VIDEO,0))->m_fAspect = g_renderManager.GetAspectRatio();
4080  
-      ((CStreamDetailVideo*)details.GetNthStream(CStreamDetail::VIDEO,0))->m_iDuration = GetTotalTime() / 1000;
  4158
+      /* 
  4159
+       * We can only obtain the aspect & duration from dvdplayer when the Process() thread is running
  4160
+       * and UpdatePlayState() has been called at least once. In this case dvdplayer duration/AR will
  4161
+       * return 0 and we'll have to fallback to the (less accurate) info from the demuxer.
  4162
+       */
  4163
+      float aspect = m_player_video.GetAspectRatio();
  4164
+      if (aspect > 0.0f)
  4165
+        ((CStreamDetailVideo*)details.GetNthStream(CStreamDetail::VIDEO,0))->m_fAspect = aspect;
  4166
+
  4167
+      int64_t duration = GetTotalTime() / 1000;
  4168
+      if (duration > 0)
  4169
+        ((CStreamDetailVideo*)details.GetNthStream(CStreamDetail::VIDEO,0))->m_iDuration = duration;
4081 4170
     }
4082 4171
     return result;
4083 4172
   }
22  xbmc/cores/omxplayer/OMXPlayer.h
@@ -74,6 +74,7 @@ class COMXCurrentStream
74 74
   int              source;
75 75
   double           dts;    // last dts from demuxer, used to find disncontinuities
76 76
   double           dur;    // last frame expected duration
  77
+  double           dts_state; // when did we last send a playback state update
77 78
   CDVDStreamInfo   hint;   // stream hints, used to notice stream changes
78 79
   void*            stream; // pointer or integer, identifying stream playing. if it changes stream changed
79 80
   int              changes; // remembered counter from stream to track codec changes
@@ -96,6 +97,7 @@ class COMXCurrentStream
96 97
     id     = -1;
97 98
     source = STREAM_SOURCE_NONE;
98 99
     dts    = DVD_NOPTS_VALUE;
  100
+    dts_state = DVD_NOPTS_VALUE;
99 101
     dur    = DVD_NOPTS_VALUE;
100 102
     hint.Clear();
101 103
     stream = NULL;
@@ -366,15 +368,27 @@ class COMXPlayer : public IPlayer, public CThread, public IDVDPlayer
366 368
     int iSelectedAudioStream; // mpeg stream id, or -1 if disabled
367 369
   } m_dvd;
368 370
 
  371
+  enum ETimeSource
  372
+  {
  373
+    ETIMESOURCE_CLOCK,
  374
+    ETIMESOURCE_INPUT,
  375
+    ETIMESOURCE_MENU,
  376
+  };
  377
+
  378
+  friend class OMXPlayerVideo;
  379
+  friend class OMXPlayerAudio;
  380
+
369 381
   struct SPlayerState
370 382
   {
371 383
     SPlayerState() { Clear(); }
372 384
     void Clear()
373 385
     {
  386
+      player        = 0;
374 387
       timestamp     = 0;
375 388
       time          = 0;
376 389
       time_total    = 0;
377 390
       time_offset   = 0;
  391
+      time_src      = ETIMESOURCE_CLOCK;
378 392
       dts           = DVD_NOPTS_VALUE;
379 393
       player_state  = "";
380 394
       chapter       = 0;
@@ -392,11 +406,14 @@ class COMXPlayer : public IPlayer, public CThread, public IDVDPlayer
392 406
       cache_offset  = 0.0;
393 407
     }
394 408
 
  409
+    int    player;            // source of this data
  410
+
395 411
     double timestamp;         // last time of update
396 412
     double time_offset;       // difference between time and pts
397 413
 
398 414
     double time;              // current playback time
399 415
     double time_total;        // total playback time
  416
+    ETimeSource time_src;     // current time source
400 417
     double dts;               // last known dts
401 418
 
402 419
     std::string player_state;  // full player state
@@ -418,7 +435,7 @@ class COMXPlayer : public IPlayer, public CThread, public IDVDPlayer
418 435
     double  cache_level;   // current estimated required cache level
419 436
     double  cache_delay;   // time until cache is expected to reach estimated level
420 437
     double  cache_offset;  // percentage of file ahead of current position
421  
-  } m_State;
  438
+  } m_State, m_StateInput;
422 439
   CCriticalSection m_StateSection;
423 440
 
424 441
   CEdl m_Edl;
@@ -481,4 +498,7 @@ class COMXPlayer : public IPlayer, public CThread, public IDVDPlayer
481 498
   bool                    m_change_volume;
482 499
   CDVDOverlayContainer    m_overlayContainer;
483 500
   ECacheState             m_caching;
  501
+
  502
+  bool m_HasVideo;
  503
+  bool m_HasAudio;
484 504
 };
12  xbmc/cores/omxplayer/OMXPlayerAudio.cpp
@@ -569,6 +569,18 @@ void OMXPlayerAudio::Process()
569 569
       if(m_started)
570 570
         m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_AUDIO));
571 571
     }
  572
+    else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
  573
+    {
  574
+      COMXPlayer::SPlayerState& state = ((CDVDMsgType<COMXPlayer::SPlayerState>*)pMsg)->m_value;
  575
+
  576
+      if(state.time_src == COMXPlayer::ETIMESOURCE_CLOCK)
  577
+        state.time      = DVD_TIME_TO_MSEC(m_av_clock->OMXMediaTime(true, true));
  578
+        //state.time      = DVD_TIME_TO_MSEC(m_av_clock->GetClock(state.timestamp) + state.time_offset);
  579
+      else
  580
+        state.timestamp = m_av_clock->GetAbsoluteClock();
  581
+      state.player    = DVDPLAYER_AUDIO;
  582
+      m_messageParent.Put(pMsg->Acquire());
  583
+    }
572 584
     else if (pMsg->IsType(CDVDMsg::GENERAL_EOF))
573 585
     {
574 586
       CLog::Log(LOGDEBUG, "COMXPlayerAudio - CDVDMsg::GENERAL_EOF");
13  xbmc/cores/omxplayer/OMXPlayerVideo.cpp
@@ -42,6 +42,7 @@
42 42
 #include "DVDOverlayRenderer.h"
43 43
 #include "settings/GUISettings.h"
44 44
 #include "settings/Settings.h"
  45
+#include "settings/MediaSettings.h"
45 46
 #include "cores/VideoRenderers/RenderFormats.h"
46 47
 #include "cores/VideoRenderers/RenderFlags.h"
47 48
 
@@ -490,6 +491,18 @@ void OMXPlayerVideo::Process()
490 491
       if(m_started)
491 492
         m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_VIDEO));
492 493
     }
  494
+    else if (pMsg->IsType(CDVDMsg::PLAYER_DISPLAYTIME))
  495
+    {
  496
+      COMXPlayer::SPlayerState& state = ((CDVDMsgType<COMXPlayer::SPlayerState>*)pMsg)->m_value;
  497
+
  498
+      if(state.time_src == COMXPlayer::ETIMESOURCE_CLOCK)
  499
+        state.time      = DVD_TIME_TO_MSEC(m_av_clock->OMXMediaTime(true, true));
  500
+        //state.time      = DVD_TIME_TO_MSEC(m_av_clock->GetClock(state.timestamp) + state.time_offset);
  501
+      else
  502
+        state.timestamp = m_av_clock->GetAbsoluteClock();
  503
+      state.player    = DVDPLAYER_VIDEO;
  504
+      m_messageParent.Put(pMsg->Acquire());
  505
+    }
493 506
     else if (pMsg->IsType(CDVDMsg::GENERAL_STREAMCHANGE))
494 507
     {
495 508
       COMXMsgVideoCodecChange* msg(static_cast<COMXMsgVideoCodecChange*>(pMsg));
2  xbmc/cores/omxplayer/OMXPlayerVideo.h
@@ -38,6 +38,7 @@
38 38
 #include "DVDMessageQueue.h"
39 39
 #include "utils/BitstreamStats.h"
40 40
 #include "linux/DllBCM.h"
  41
+#include "cores/VideoRenderers/RenderManager.h"
41 42
 
42 43
 using namespace std;
43 44
 
@@ -125,6 +126,7 @@ class OMXPlayerVideo : public CThread
125 126
   void EnableSubtitle(bool bEnable)                 { m_bRenderSubs = bEnable; }
126 127
   bool IsSubtitleEnabled()                          { return m_bRenderSubs; }
127 128
   void EnableFullscreen(bool bEnable)               { m_bAllowFullscreen = bEnable; }
  129
+  float GetAspectRatio()                            { return g_renderManager.GetAspectRatio(); }
128 130
   void SetFlags(unsigned flags)                     { m_flags = flags; };
129 131
   int GetFreeSpace();
130 132
   void  SetVideoRect(const CRect &SrcRect, const CRect &DestRect);

0 notes on commit 3caf659

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