乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      KODI(原XBMC)二次開(kāi)發(fā)完全解析(三)

       昵稱14340561 2020-08-07

        上篇講到player的建立流程KODI(原XBMC)二次開(kāi)發(fā)完全解析(二)-------創(chuàng)建player,接著上篇確定哪一個(gè)才是真正干活的player。

      m_pPlayer->CreatePlayer(newPlayer, *this);//創(chuàng)建player,下篇重點(diǎn)講   這個(gè)就開(kāi)始創(chuàng)建player,這個(gè)m_pPlayer就是xbmc/ApplicationPlayer.h的實(shí)例,調(diào)用源碼如下:

      1. void CApplicationPlayer::CreatePlayer(const std::string &player, IPlayerCallback& callback)
      2. {
      3. CSingleLock lock(m_player_lock);
      4. if (!m_pPlayer)
      5. {
      6. m_pPlayer.reset(CPlayerCoreFactory::GetInstance().CreatePlayer(player, callback));
      7. }
      8. }

      player就是需要?jiǎng)?chuàng)建的player,繼續(xù)查看CPlayerCoreFactory::GetInstance().CreatePlayer(player, callback)

      1. IPlayer* CPlayerCoreFactory::CreatePlayer(const std::string& nameId, IPlayerCallback& callback) const
      2. {
      3. CSingleLock lock(m_section);
      4. size_t idx = GetPlayerIndex(nameId);
      5. if (m_vecPlayerConfigs.empty() || idx > m_vecPlayerConfigs.size())
      6. return nullptr;
      7. return m_vecPlayerConfigs[idx]->CreatePlayer(callback);
      8. }

      根據(jù)nameId調(diào)用PlayerCoreConfig.h創(chuàng)建Player

      1. IPlayer* CreatePlayer(IPlayerCallback& callback) const
      2. {
      3. IPlayer* pPlayer;
      4. if (m_type.compare("video") == 0)
      5. {
      6. pPlayer = new CVideoPlayer(callback);//創(chuàng)建VideoPlayer
      7. }
      8. else if (m_type.compare("music") == 0)
      9. {
      10. pPlayer = new PAPlayer(callback);
      11. }
      12. else if (m_type.compare("external") == 0)
      13. {
      14. pPlayer = new CExternalPlayer(callback);
      15. }
      16. #if defined(HAS_UPNP)
      17. else if (m_type.compare("remote") == 0)
      18. {
      19. pPlayer = new UPNP::CUPnPPlayer(callback, m_id.c_str());
      20. }
      21. #endif
      22. else
      23. return nullptr;
      24. pPlayer->m_name = m_name;
      25. pPlayer->m_type = m_type;
      26. if (pPlayer->Initialize(m_config))
      27. {
      28. return pPlayer;
      29. }
      30. else
      31. {
      32. SAFE_DELETE(pPlayer);
      33. return nullptr;
      34. }
      35. }

      根據(jù)type類型,創(chuàng)建需要的player,至此,我們找到了VideoPlayer,這個(gè)才是這篇要說(shuō)的重點(diǎn),下面先查看VideoPlayer.h文件,位于xbmc/cores/VideoPlayer/VideoPlayer.h

      1. class CVideoPlayer : public IPlayer, public CThread, public IVideoPlayer, public IDispResource, public IRenderMsg
      2. {
      3. public:
      4. CVideoPlayer(IPlayerCallback& callback);
      5. virtual ~CVideoPlayer();
      6. virtual bool OpenFile(const CFileItem& file, const CPlayerOptions &options);
      7. virtual bool CloseFile(bool reopen = false);
      8. virtual bool IsPlaying() const;
      9. virtual void Pause() override;
      10. virtual bool HasVideo() const;
      11. virtual bool HasAudio() const;
      12. virtual bool HasRDS() const;
      13. virtual bool IsPassthrough() const;
      14. virtual bool CanSeek();
      15. virtual void Seek(bool bPlus, bool bLargeStep, bool bChapterOverride);
      16. virtual bool SeekScene(bool bPlus = true);
      17. virtual void SeekPercentage(float iPercent);
      18. virtual float GetPercentage();
      19. virtual float GetCachePercentage();
      20. virtual void SetVolume(float nVolume) override;
      21. virtual void SetMute(bool bOnOff) override;
      22. virtual void SetDynamicRangeCompression(long drc) override;
      23. virtual bool CanRecord();
      24. virtual bool IsRecording();
      25. virtual bool CanPause();
      26. virtual bool Record(bool bOnOff);
      27. virtual void SetAVDelay(float fValue = 0.0f);
      28. virtual float GetAVDelay();
      29. virtual bool IsInMenu() const override;
      30. virtual bool HasMenu() const override;
      31. virtual void SetSubTitleDelay(float fValue = 0.0f);
      32. virtual float GetSubTitleDelay();
      33. virtual int GetSubtitleCount();
      34. virtual int GetSubtitle();
      35. virtual void GetSubtitleStreamInfo(int index, SPlayerSubtitleStreamInfo &info);
      36. virtual void SetSubtitle(int iStream);
      37. virtual bool GetSubtitleVisible();
      38. virtual void SetSubtitleVisible(bool bVisible);
      39. virtual void AddSubtitle(const std::string& strSubPath);
      40. virtual int GetAudioStreamCount();
      41. virtual int GetAudioStream();
      42. virtual void SetAudioStream(int iStream);
      43. virtual int GetVideoStream() const override;
      44. virtual int GetVideoStreamCount() const override;
      45. virtual void GetVideoStreamInfo(int streamId, SPlayerVideoStreamInfo &info) override;
      46. virtual void SetVideoStream(int iStream);
      47. virtual TextCacheStruct_t* GetTeletextCache();
      48. virtual void LoadPage(int p, int sp, unsigned char* buffer);
      49. virtual std::string GetRadioText(unsigned int line);
      50. virtual int GetChapterCount();
      51. virtual int GetChapter();
      52. virtual void GetChapterName(std::string& strChapterName, int chapterIdx=-1);
      53. virtual int64_t GetChapterPos(int chapterIdx=-1);
      54. virtual int SeekChapter(int iChapter);
      55. virtual void SeekTime(int64_t iTime);
      56. virtual bool SeekTimeRelative(int64_t iTime);
      57. virtual int64_t GetTime();
      58. virtual int64_t GetTotalTime();
      59. virtual void SetSpeed(float speed) override;
      60. virtual float GetSpeed() override;
      61. virtual bool SupportsTempo() override;
      62. virtual bool OnAction(const CAction &action);
      63. virtual int GetSourceBitrate();
      64. virtual bool GetStreamDetails(CStreamDetails &details);
      65. virtual void GetAudioStreamInfo(int index, SPlayerAudioStreamInfo &info);
      66. virtual std::string GetPlayerState();
      67. virtual bool SetPlayerState(const std::string& state);
      68. virtual std::string GetPlayingTitle();
      69. virtual bool SwitchChannel(const PVR::CPVRChannelPtr &channel);
      70. virtual void FrameMove();
      71. virtual void Render(bool clear, uint32_t alpha = 255, bool gui = true);
      72. virtual void FlushRenderer();
      73. virtual void SetRenderViewMode(int mode);
      74. float GetRenderAspectRatio();
      75. virtual void TriggerUpdateResolution();
      76. virtual bool IsRenderingVideo();
      77. virtual bool IsRenderingGuiLayer();
      78. virtual bool IsRenderingVideoLayer();
      79. virtual bool Supports(EINTERLACEMETHOD method) override;
      80. virtual EINTERLACEMETHOD GetDeinterlacingMethodDefault() override;
      81. virtual bool Supports(ESCALINGMETHOD method) override;
      82. virtual bool Supports(ERENDERFEATURE feature) override;
      83. virtual unsigned int RenderCaptureAlloc();
      84. virtual void RenderCapture(unsigned int captureId, unsigned int width, unsigned int height, int flags);
      85. virtual void RenderCaptureRelease(unsigned int captureId);
      86. virtual bool RenderCaptureGetPixels(unsigned int captureId, unsigned int millis, uint8_t *buffer, unsigned int size);
      87. // IDispResource interface
      88. virtual void OnLostDisplay();
      89. virtual void OnResetDisplay();
      90. virtual bool IsCaching() const override;
      91. virtual int GetCacheLevel() const override;
      92. virtual int OnDVDNavResult(void* pData, int iMessage) override;
      93. void GetVideoResolution(unsigned int &width, unsigned int &height) override;
      94. protected:
      95. friend class CSelectionStreams;
      96. virtual void OnStartup();
      97. virtual void OnExit();
      98. virtual void Process();
      99. virtual void VideoParamsChange() override;
      100. virtual void GetDebugInfo(std::string &audio, std::string &video, std::string &general) override;
      101. virtual void UpdateClockSync(bool enabled) override;
      102. virtual void UpdateRenderInfo(CRenderInfo &info) override;
      103. virtual void UpdateRenderBuffers(int queued, int discard, int free) override;
      104. void CreatePlayers();
      105. void DestroyPlayers();
      106. bool OpenStream(CCurrentStream& current, int64_t demuxerId, int iStream, int source, bool reset = true);
      107. bool OpenAudioStream(CDVDStreamInfo& hint, bool reset = true);
      108. bool OpenVideoStream(CDVDStreamInfo& hint, bool reset = true);
      109. bool OpenSubtitleStream(CDVDStreamInfo& hint);
      110. bool OpenTeletextStream(CDVDStreamInfo& hint);
      111. bool OpenRadioRDSStream(CDVDStreamInfo& hint);
      112. /** \brief Switches forced subtitles to forced subtitles matching the language of the current audio track.
      113. * If these are not available, subtitles are disabled.
      114. */
      115. void AdaptForcedSubtitles();
      116. bool CloseStream(CCurrentStream& current, bool bWaitForBuffers);
      117. bool CheckIsCurrent(CCurrentStream& current, CDemuxStream* stream, DemuxPacket* pkg);
      118. void ProcessPacket(CDemuxStream* pStream, DemuxPacket* pPacket);
      119. void ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket);
      120. void ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket);
      121. void ProcessSubData(CDemuxStream* pStream, DemuxPacket* pPacket);
      122. void ProcessTeletextData(CDemuxStream* pStream, DemuxPacket* pPacket);
      123. void ProcessRadioRDSData(CDemuxStream* pStream, DemuxPacket* pPacket);
      124. bool ShowPVRChannelInfo();
      125. int AddSubtitleFile(const std::string& filename, const std::string& subfilename = "");
      126. void SetSubtitleVisibleInternal(bool bVisible);
      127. /**
      128. * one of the DVD_PLAYSPEED defines
      129. */
      130. void SetPlaySpeed(int iSpeed);
      131. int GetPlaySpeed() { return m_playSpeed; }
      132. enum ECacheState
      133. {
      134. CACHESTATE_DONE = 0,
      135. CACHESTATE_FULL, // player is filling up the demux queue
      136. CACHESTATE_INIT, // player is waiting for first packet of each stream
      137. CACHESTATE_PLAY, // player is waiting for players to not be stalled
      138. CACHESTATE_FLUSH, // temporary state player will choose startup between init or full
      139. };
      140. void SetCaching(ECacheState state);
      141. int64_t GetTotalTimeInMsec();
      142. double GetQueueTime();
      143. bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset);
      144. void FlushBuffers(double pts, bool accurate, bool sync);
      145. void HandleMessages();
      146. void HandlePlaySpeed();
      147. bool IsInMenuInternal() const;
      148. void SynchronizeDemuxer();
      149. void CheckAutoSceneSkip();
      150. bool CheckContinuity(CCurrentStream& current, DemuxPacket* pPacket);
      151. bool CheckSceneSkip(CCurrentStream& current);
      152. bool CheckPlayerInit(CCurrentStream& current);
      153. void UpdateCorrection(DemuxPacket* pkt, double correction);
      154. void UpdateTimestamps(CCurrentStream& current, DemuxPacket* pPacket);
      155. IDVDStreamPlayer* GetStreamPlayer(unsigned int player);
      156. void SendPlayerMessage(CDVDMsg* pMsg, unsigned int target);
      157. bool ReadPacket(DemuxPacket*& packet, CDemuxStream*& stream);
      158. bool IsValidStream(CCurrentStream& stream);
      159. bool IsBetterStream(CCurrentStream& current, CDemuxStream* stream);
      160. void CheckBetterStream(CCurrentStream& current, CDemuxStream* stream);
      161. void CheckStreamChanges(CCurrentStream& current, CDemuxStream* stream);
      162. bool CheckDelayedChannelEntry(void);
      163. bool OpenInputStream();
      164. bool OpenDemuxStream();
      165. void CloseDemuxer();
      166. void OpenDefaultStreams(bool reset = true);
      167. void UpdateApplication(double timeout);
      168. void UpdatePlayState(double timeout);
      169. void UpdateStreamInfos();
      170. void GetGeneralInfo(std::string& strVideoInfo);
      171. double m_UpdateApplication;
      172. bool m_players_created;
      173. bool m_bAbortRequest;
      174. ECacheState m_caching;
      175. XbmcThreads::EndTime m_cachingTimer;
      176. CFileItem m_item;
      177. XbmcThreads::EndTime m_ChannelEntryTimeOut;
      178. std::unique_ptr<CProcessInfo> m_processInfo;
      179. CCurrentStream m_CurrentAudio;
      180. CCurrentStream m_CurrentVideo;
      181. CCurrentStream m_CurrentSubtitle;
      182. CCurrentStream m_CurrentTeletext;
      183. CCurrentStream m_CurrentRadioRDS;
      184. CSelectionStreams m_SelectionStreams;
      185. std::atomic_int m_playSpeed;
      186. std::atomic_int m_newPlaySpeed;
      187. int m_streamPlayerSpeed;
      188. struct SSpeedState
      189. {
      190. double lastpts; // holds last display pts during ff/rw operations
      191. int64_t lasttime;
      192. int lastseekpts;
      193. double lastabstime;
      194. } m_SpeedState;
      195. std::atomic_bool m_canTempo;
      196. int m_errorCount;
      197. double m_offset_pts;
      198. CDVDMessageQueue m_messenger; // thread messenger
      199. IDVDStreamPlayerVideo *m_VideoPlayerVideo; // video part
      200. IDVDStreamPlayerAudio *m_VideoPlayerAudio; // audio part
      201. CVideoPlayerSubtitle *m_VideoPlayerSubtitle; // subtitle part
      202. CDVDTeletextData *m_VideoPlayerTeletext; // teletext part
      203. CDVDRadioRDSData *m_VideoPlayerRadioRDS; // rds part
      204. CDVDClock m_clock; // master clock
      205. CDVDOverlayContainer m_overlayContainer;
      206. CDVDInputStream* m_pInputStream; // input stream for current playing file
      207. CDVDDemux* m_pDemuxer; // demuxer for current playing file
      208. CDVDDemux* m_pSubtitleDemuxer;
      209. CDVDDemuxCC* m_pCCDemuxer;
      210. CRenderManager m_renderManager;
      211. struct SDVDInfo
      212. {
      213. void Clear()
      214. {
      215. state = DVDSTATE_NORMAL;
      216. iSelectedSPUStream = -1;
      217. iSelectedAudioStream = -1;
      218. iSelectedVideoStream = -1;
      219. iDVDStillTime = 0;
      220. iDVDStillStartTime = 0;
      221. syncClock = false;
      222. }
      223. int state; // current dvdstate
      224. bool syncClock;
      225. unsigned int iDVDStillTime; // total time in ticks we should display the still before continuing
      226. unsigned int iDVDStillStartTime; // time in ticks when we started the still
      227. int iSelectedSPUStream; // mpeg stream id, or -1 if disabled
      228. int iSelectedAudioStream; // mpeg stream id, or -1 if disabled
      229. int iSelectedVideoStream; // mpeg stream id or angle, -1 if disabled
      230. } m_dvd;
      231. friend class CVideoPlayerVideo;
      232. friend class CVideoPlayerAudio;
      233. #ifdef HAS_OMXPLAYER
      234. friend class OMXPlayerVideo;
      235. friend class OMXPlayerAudio;
      236. #endif
      237. SPlayerState m_State;
      238. CCriticalSection m_StateSection;
      239. XbmcThreads::EndTime m_syncTimer;
      240. CEvent m_ready;
      241. CEdl m_Edl;
      242. bool m_SkipCommercials;
      243. CPlayerOptions m_PlayerOptions;
      244. bool m_HasVideo;
      245. bool m_HasAudio;
      246. std::atomic<bool> m_displayLost;
      247. // omxplayer variables
      248. struct SOmxPlayerState m_OmxPlayerState;
      249. bool m_omxplayer_mode; // using omxplayer acceleration
      250. XbmcThreads::EndTime m_player_status_timer;
      251. };

      其中定義了很多諸如seek、pause函數(shù),看完這個(gè)就確定我們找的VideoPlayer是沒(méi)有錯(cuò)誤的,而VideoPlayer extends Thread,這個(gè)子線程明顯就是要解析視頻的線程,查看當(dāng)前thread的Process函數(shù)

      1. void CVideoPlayer::Process()
      2. {
      3. CFFmpegLog::SetLogLevel(1);
      4. if (!OpenInputStream())//創(chuàng)建輸入流
      5. {
      6. m_bAbortRequest = true;
      7. return;
      8. }
      9. if (CDVDInputStream::IMenus* ptr = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
      10. {
      11. CLog::Log(LOGNOTICE, "VideoPlayer: playing a file with menu's");
      12. if(dynamic_cast<CDVDInputStreamNavigator*>(m_pInputStream))
      13. m_PlayerOptions.starttime = 0;
      14. if(!m_PlayerOptions.state.empty())
      15. ptr->SetState(m_PlayerOptions.state);
      16. else if(CDVDInputStreamNavigator* nav = dynamic_cast<CDVDInputStreamNavigator*>(m_pInputStream))
      17. nav->EnableSubtitleStream(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_SubtitleOn);
      18. CMediaSettings::GetInstance().GetCurrentVideoSettings().m_SubtitleCached = true;
      19. }
      20. if(!OpenDemuxStream())//創(chuàng)建demux
      21. {
      22. m_bAbortRequest = true;
      23. return;
      24. }
      25. // give players a chance to reconsider now codecs are known
      26. CreatePlayers();
      27. // allow renderer to switch to fullscreen if requested
      28. m_VideoPlayerVideo->EnableFullscreen(m_PlayerOptions.fullscreen);
      29. if (m_omxplayer_mode)
      30. {
      31. if (!m_OmxPlayerState.av_clock.OMXInitialize(&m_clock))
      32. m_bAbortRequest = true;
      33. if (CSettings::GetInstance().GetInt(CSettings::SETTING_VIDEOPLAYER_ADJUSTREFRESHRATE) != ADJUST_REFRESHRATE_OFF)
      34. m_OmxPlayerState.av_clock.HDMIClockSync();
      35. m_OmxPlayerState.av_clock.OMXStateIdle();
      36. m_OmxPlayerState.av_clock.OMXStateExecute();
      37. m_OmxPlayerState.av_clock.OMXStop();
      38. m_OmxPlayerState.av_clock.OMXPause();
      39. }
      40. OpenDefaultStreams();
      41. // look for any EDL files
      42. m_Edl.Clear();
      43. if (m_CurrentVideo.id >= 0 && m_CurrentVideo.hint.fpsrate > 0 && m_CurrentVideo.hint.fpsscale > 0)
      44. {
      45. float fFramesPerSecond = (float)m_CurrentVideo.hint.fpsrate / (float)m_CurrentVideo.hint.fpsscale;
      46. m_Edl.ReadEditDecisionLists(m_item.GetPath(), fFramesPerSecond, m_CurrentVideo.hint.height);
      47. }
      48. /*
      49. * Check to see if the demuxer should start at something other than time 0. This will be the case
      50. * if there was a start time specified as part of the "Start from where last stopped" (aka
      51. * auto-resume) feature or if there is an EDL cut or commercial break that starts at time 0.
      52. */
      53. CEdl::Cut cut;
      54. int starttime = 0;
      55. if (m_PlayerOptions.starttime > 0 || m_PlayerOptions.startpercent > 0)
      56. {
      57. if (m_PlayerOptions.startpercent > 0 && m_pDemuxer)
      58. {
      59. int playerStartTime = (int)( ( (float) m_pDemuxer->GetStreamLength() ) * ( m_PlayerOptions.startpercent/(float)100 ) );
      60. starttime = m_Edl.RestoreCutTime(playerStartTime);
      61. }
      62. else
      63. {
      64. starttime = m_Edl.RestoreCutTime(m_PlayerOptions.starttime * 1000); // s to ms
      65. }
      66. CLog::Log(LOGDEBUG, "%s - Start position set to last stopped position: %d", __FUNCTION__, starttime);
      67. }
      68. else if (m_Edl.InCut(starttime, &cut))
      69. {
      70. if (cut.action == CEdl::CUT)
      71. {
      72. starttime = cut.end;
      73. CLog::Log(LOGDEBUG, "%s - Start position set to end of first cut: %d", __FUNCTION__, starttime);
      74. }
      75. else if (cut.action == CEdl::COMM_BREAK)
      76. {
      77. if (m_SkipCommercials)
      78. {
      79. starttime = cut.end;
      80. CLog::Log(LOGDEBUG, "%s - Start position set to end of first commercial break: %d", __FUNCTION__, starttime);
      81. }
      82. std::string strTimeString = StringUtils::SecondsToTimeString(cut.end / 1000, TIME_FORMAT_MM_SS);
      83. CGUIDialogKaiToast::QueueNotification(g_localizeStrings.Get(25011), strTimeString);
      84. }
      85. }
      86. if (starttime > 0)//判斷上次播放時(shí)長(zhǎng),選擇從上次播放時(shí)開(kāi)始播放
      87. {
      88. double startpts = DVD_NOPTS_VALUE;
      89. if (m_pDemuxer)
      90. {
      91. if (m_pDemuxer->SeekTime(starttime, false, &startpts))
      92. CLog::Log(LOGDEBUG, "%s - starting demuxer from: %d", __FUNCTION__, starttime);
      93. else
      94. CLog::Log(LOGDEBUG, "%s - failed to start demuxing from: %d", __FUNCTION__, starttime);
      95. }
      96. if (m_pSubtitleDemuxer)
      97. {
      98. if(m_pSubtitleDemuxer->SeekTime(starttime, false, &startpts))
      99. CLog::Log(LOGDEBUG, "%s - starting subtitle demuxer from: %d", __FUNCTION__, starttime);
      100. else
      101. CLog::Log(LOGDEBUG, "%s - failed to start subtitle demuxing from: %d", __FUNCTION__, starttime);
      102. }
      103. m_clock.Discontinuity(DVD_MSEC_TO_TIME(starttime));
      104. }
      105. // make sure application know our info
      106. UpdateApplication(0);
      107. UpdatePlayState(0);
      108. if(m_PlayerOptions.identify == false)
      109. m_callback.OnPlayBackStarted();
      110. // we are done initializing now, set the readyevent
      111. m_ready.Set();
      112. SetCaching(CACHESTATE_FLUSH);
      113. while (!m_bAbortRequest)//開(kāi)啟循環(huán)demux,將數(shù)據(jù)拋給下層decode
      114. {
      115. #ifdef HAS_OMXPLAYER
      116. if (m_omxplayer_mode && OMXDoProcessing(m_OmxPlayerState, m_playSpeed, m_VideoPlayerVideo, m_VideoPlayerAudio, m_CurrentAudio, m_CurrentVideo, m_HasVideo, m_HasAudio, m_renderManager))
      117. {
      118. CloseStream(m_CurrentVideo, false);
      119. OpenStream(m_CurrentVideo, m_CurrentVideo.demuxerId, m_CurrentVideo.id, m_CurrentVideo.source);
      120. if (m_State.canseek)
      121. {
      122. CDVDMsgPlayerSeek::CMode mode;
      123. mode.time = (int)GetTime();
      124. mode.backward = true;
      125. mode.accurate = true;
      126. mode.sync = true;
      127. m_messenger.Put(new CDVDMsgPlayerSeek(mode));
      128. }
      129. }
      130. #endif
      131. // check display lost
      132. if (m_displayLost)
      133. {
      134. Sleep(50);
      135. continue;
      136. }
      137. // check if in a cut or commercial break that should be automatically skipped
      138. CheckAutoSceneSkip();
      139. // handle messages send to this thread, like seek or demuxer reset requests
      140. HandleMessages();
      141. if(m_bAbortRequest)
      142. break;
      143. // should we open a new input stream?
      144. if(!m_pInputStream)
      145. {
      146. if (OpenInputStream() == false)
      147. {
      148. m_bAbortRequest = true;
      149. break;
      150. }
      151. }
      152. // should we open a new demuxer?
      153. if(!m_pDemuxer)
      154. {
      155. if (m_pInputStream->NextStream() == CDVDInputStream::NEXTSTREAM_NONE)
      156. break;
      157. if (m_pInputStream->IsEOF())
      158. break;
      159. if (OpenDemuxStream() == false)
      160. {
      161. m_bAbortRequest = true;
      162. break;
      163. }
      164. // on channel switch we don't want to close stream players at this
      165. // time. we'll get the stream change event later
      166. if (!m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER) ||
      167. !m_SelectionStreams.m_Streams.empty())
      168. OpenDefaultStreams();
      169. UpdateApplication(0);
      170. UpdatePlayState(0);
      171. }
      172. // handle eventual seeks due to playspeed
      173. HandlePlaySpeed();
      174. // update player state
      175. UpdatePlayState(200);
      176. // update application with our state
      177. UpdateApplication(1000);
      178. // make sure we run subtitle process here
      179. m_VideoPlayerSubtitle->Process(m_clock.GetClock() + m_State.time_offset - m_VideoPlayerVideo->GetSubtitleDelay(), m_State.time_offset);
      180. if (CheckDelayedChannelEntry())
      181. continue;
      182. // if the queues are full, no need to read more
      183. if ((!m_VideoPlayerAudio->AcceptsData() && m_CurrentAudio.id >= 0) ||
      184. (!m_VideoPlayerVideo->AcceptsData() && m_CurrentVideo.id >= 0))
      185. {
      186. Sleep(10);
      187. continue;
      188. }
      189. // always yield to players if they have data levels > 50 percent
      190. if((m_VideoPlayerAudio->GetLevel() > 50 || m_CurrentAudio.id < 0)
      191. && (m_VideoPlayerVideo->GetLevel() > 50 || m_CurrentVideo.id < 0))
      192. Sleep(0);
      193. DemuxPacket* pPacket = NULL;
      194. CDemuxStream *pStream = NULL;
      195. ReadPacket(pPacket, pStream);//開(kāi)始將流封包,方便傳給下一層decode
      196. if (pPacket && !pStream)
      197. {
      198. /* probably a empty packet, just free it and move on */
      199. CDVDDemuxUtils::FreeDemuxPacket(pPacket);
      200. continue;
      201. }
      202. if (!pPacket)
      203. {
      204. // when paused, demuxer could be be returning empty
      205. if (m_playSpeed == DVD_PLAYSPEED_PAUSE)
      206. continue;
      207. // check for a still frame state
      208. if (CDVDInputStream::IMenus* pStream = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
      209. {
      210. // stills will be skipped
      211. if(m_dvd.state == DVDSTATE_STILL)
      212. {
      213. if (m_dvd.iDVDStillTime > 0)
      214. {
      215. if ((XbmcThreads::SystemClockMillis() - m_dvd.iDVDStillStartTime) >= m_dvd.iDVDStillTime)
      216. {
      217. m_dvd.iDVDStillTime = 0;
      218. m_dvd.iDVDStillStartTime = 0;
      219. m_dvd.state = DVDSTATE_NORMAL;
      220. pStream->SkipStill();
      221. continue;
      222. }
      223. }
      224. }
      225. }
      226. // if there is another stream available, reopen demuxer
      227. CDVDInputStream::ENextStream next = m_pInputStream->NextStream();
      228. if(next == CDVDInputStream::NEXTSTREAM_OPEN)
      229. {
      230. CloseDemuxer();
      231. SetCaching(CACHESTATE_DONE);
      232. CLog::Log(LOGNOTICE, "VideoPlayer: next stream, wait for old streams to be finished");
      233. CloseStream(m_CurrentAudio, true);
      234. CloseStream(m_CurrentVideo, true);
      235. m_CurrentAudio.Clear();
      236. m_CurrentVideo.Clear();
      237. m_CurrentSubtitle.Clear();
      238. continue;
      239. }
      240. // input stream asked us to just retry
      241. if(next == CDVDInputStream::NEXTSTREAM_RETRY)
      242. {
      243. Sleep(100);
      244. continue;
      245. }
      246. // make sure we tell all players to finish it's data
      247. if (m_omxplayer_mode && !m_OmxPlayerState.bOmxSentEOFs)
      248. {
      249. if(m_CurrentAudio.inited)
      250. m_OmxPlayerState.bOmxWaitAudio = true;
      251. if(m_CurrentVideo.inited)
      252. m_OmxPlayerState.bOmxWaitVideo = true;
      253. m_OmxPlayerState.bOmxSentEOFs = true;
      254. }
      255. if(m_CurrentAudio.inited)
      256. m_VideoPlayerAudio->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));
      257. if(m_CurrentVideo.inited)
      258. m_VideoPlayerVideo->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));
      259. if(m_CurrentSubtitle.inited)
      260. m_VideoPlayerSubtitle->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));
      261. if(m_CurrentTeletext.inited)
      262. m_VideoPlayerTeletext->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));
      263. if(m_CurrentRadioRDS.inited)
      264. m_VideoPlayerRadioRDS->SendMessage(new CDVDMsg(CDVDMsg::GENERAL_EOF));
      265. m_CurrentAudio.inited = false;
      266. m_CurrentVideo.inited = false;
      267. m_CurrentSubtitle.inited = false;
      268. m_CurrentTeletext.inited = false;
      269. m_CurrentRadioRDS.inited = false;
      270. // if we are caching, start playing it again
      271. SetCaching(CACHESTATE_DONE);
      272. // while players are still playing, keep going to allow seekbacks
      273. if(m_VideoPlayerAudio->HasData()
      274. || m_VideoPlayerVideo->HasData())
      275. {
      276. Sleep(100);
      277. continue;
      278. }
      279. #ifdef HAS_OMXPLAYER
      280. if (m_omxplayer_mode && OMXStillPlaying(m_OmxPlayerState.bOmxWaitVideo, m_OmxPlayerState.bOmxWaitAudio, m_VideoPlayerVideo->IsEOS(), m_VideoPlayerAudio->IsEOS()))
      281. {
      282. Sleep(100);
      283. continue;
      284. }
      285. #endif
      286. if (!m_pInputStream->IsEOF())
      287. CLog::Log(LOGINFO, "%s - eof reading from demuxer", __FUNCTION__);
      288. break;
      289. }
      290. // it's a valid data packet, reset error counter
      291. m_errorCount = 0;
      292. // see if we can find something better to play
      293. CheckBetterStream(m_CurrentAudio, pStream);
      294. CheckBetterStream(m_CurrentVideo, pStream);
      295. CheckBetterStream(m_CurrentSubtitle, pStream);
      296. CheckBetterStream(m_CurrentTeletext, pStream);
      297. CheckBetterStream(m_CurrentRadioRDS, pStream);
      298. // demux video stream
      299. if (CSettings::GetInstance().GetBool(CSettings::SETTING_SUBTITLES_PARSECAPTIONS) && CheckIsCurrent(m_CurrentVideo, pStream, pPacket))
      300. {
      301. if (m_pCCDemuxer)
      302. {
      303. bool first = true;
      304. while(!m_bAbortRequest)
      305. {
      306. DemuxPacket *pkt = m_pCCDemuxer->Read(first ? pPacket : NULL);
      307. if (!pkt)
      308. break;
      309. first = false;
      310. if (m_pCCDemuxer->GetNrOfStreams() != m_SelectionStreams.CountSource(STREAM_SUBTITLE, STREAM_SOURCE_VIDEOMUX))
      311. {
      312. m_SelectionStreams.Clear(STREAM_SUBTITLE, STREAM_SOURCE_VIDEOMUX);
      313. m_SelectionStreams.Update(NULL, m_pCCDemuxer, "");
      314. OpenDefaultStreams(false);
      315. }
      316. CDemuxStream *pSubStream = m_pCCDemuxer->GetStream(pkt->iStreamId);
      317. if (pSubStream && m_CurrentSubtitle.id == pkt->iStreamId && m_CurrentSubtitle.source == STREAM_SOURCE_VIDEOMUX)
      318. ProcessSubData(pSubStream, pkt);
      319. else
      320. CDVDDemuxUtils::FreeDemuxPacket(pkt);
      321. }
      322. }
      323. }
      324. if (IsInMenuInternal())
      325. {
      326. if (CDVDInputStream::IMenus* menu = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream))
      327. {
      328. double correction = menu->GetTimeStampCorrection();
      329. if (pPacket->dts != DVD_NOPTS_VALUE && pPacket->dts > correction)
      330. pPacket->dts -= correction;
      331. if (pPacket->pts != DVD_NOPTS_VALUE && pPacket->pts > correction)
      332. pPacket->pts -= correction;
      333. }
      334. if (m_dvd.syncClock)
      335. {
      336. m_clock.Discontinuity(pPacket->dts);
      337. m_dvd.syncClock = false;
      338. }
      339. }
      340. // process the packet
      341. ProcessPacket(pStream, pPacket);//將音頻流、視頻流、字幕流等分開(kāi),創(chuàng)建decode的Player并將數(shù)據(jù)傳遞給他們
      342. // update the player info for streams
      343. if (m_player_status_timer.IsTimePast())
      344. {
      345. m_player_status_timer.Set(500);
      346. UpdateStreamInfos();
      347. }
      348. }
      349. }

      第一步是OpenInputStream,調(diào)用

      1. bool CVideoPlayer::OpenInputStream()
      2. {
      3. if(m_pInputStream)
      4. SAFE_DELETE(m_pInputStream);
      5. CLog::Log(LOGNOTICE, "Creating InputStream");
      6. // correct the filename if needed
      7. std::string filename(m_item.GetPath());
      8. if (URIUtils::IsProtocol(filename, "dvd") ||
      9. StringUtils::EqualsNoCase(filename, "iso9660://video_ts/video_ts.ifo"))
      10. {
      11. m_item.SetPath(g_mediaManager.TranslateDevicePath(""));
      12. }
      13. m_pInputStream = CDVDFactoryInputStream::CreateInputStream(this, m_item, true);//創(chuàng)建
      14. if(m_pInputStream == NULL)
      15. {
      16. CLog::Log(LOGERROR, "CVideoPlayer::OpenInputStream - unable to create input stream for [%s]", CURL::GetRedacted(m_item.GetPath()).c_str());
      17. return false;
      18. }
      19. if (!m_pInputStream->Open())
      20. {
      21. CLog::Log(LOGERROR, "CVideoPlayer::OpenInputStream - error opening [%s]", CURL::GetRedacted(m_item.GetPath()).c_str());
      22. return false;
      23. }
      24. // find any available external subtitles for non dvd files
      25. if (!m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)
      26. && !m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER)
      27. && !m_pInputStream->IsStreamType(DVDSTREAM_TYPE_TV))
      28. {
      29. // find any available external subtitles
      30. std::vector<std::string> filenames;
      31. CUtil::ScanForExternalSubtitles(m_item.GetPath(), filenames);
      32. // load any subtitles from file item
      33. std::string key("subtitle:1");
      34. for(unsigned s = 1; m_item.HasProperty(key); key = StringUtils::Format("subtitle:%u", ++s))
      35. filenames.push_back(m_item.GetProperty(key).asString());
      36. for(unsigned int i=0;i<filenames.size();i++)
      37. {
      38. // if vobsub subtitle:
      39. if (URIUtils::HasExtension(filenames[i], ".idx"))
      40. {
      41. std::string strSubFile;
      42. if ( CUtil::FindVobSubPair( filenames, filenames[i], strSubFile ) )
      43. AddSubtitleFile(filenames[i], strSubFile);
      44. }
      45. else
      46. {
      47. if ( !CUtil::IsVobSub(filenames, filenames[i] ) )
      48. {
      49. AddSubtitleFile(filenames[i]);
      50. }
      51. }
      52. } // end loop over all subtitle files
      53. CMediaSettings::GetInstance().GetCurrentVideoSettings().m_SubtitleCached = true;
      54. }
      55. SetAVDelay(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_AudioDelay);
      56. SetSubTitleDelay(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_SubtitleDelay);
      57. m_clock.Reset();
      58. m_dvd.Clear();
      59. m_errorCount = 0;
      60. m_ChannelEntryTimeOut.SetInfinite();
      61. if (CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEDISPLAYASCLOCK) &&
      62. !m_pInputStream->IsRealtime())
      63. {
      64. m_canTempo = true;
      65. }
      66. else
      67. {
      68. m_canTempo = false;
      69. }
      70. return true;
      71. }

      調(diào)用m_pInputStream = CDVDFactoryInputStream::CreateInputStream(this, m_item, true);創(chuàng)建,查看位于xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp

      1. CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer, const CFileItem &fileitem, bool scanforextaudio)//根據(jù)文件類型創(chuàng)建不同的InputStream
      2. {
      3. std::string file = fileitem.GetPath();
      4. if (scanforextaudio)
      5. {
      6. // find any available external audio tracks
      7. std::vector<std::string> filenames;
      8. filenames.push_back(file);
      9. CUtil::ScanForExternalAudio(file, filenames);
      10. CUtil::ScanForExternalDemuxSub(file, filenames);
      11. if (filenames.size() >= 2)
      12. {
      13. return CreateInputStream(pPlayer, fileitem, filenames);
      14. }
      15. }
      16. ADDON::VECADDONS addons;
      17. ADDON::CBinaryAddonCache &addonCache = CServiceBroker::GetBinaryAddonCache();
      18. addonCache.GetAddons(addons, ADDON::ADDON_INPUTSTREAM);
      19. for (size_t i=0; i<addons.size(); ++i)
      20. {
      21. std::shared_ptr<ADDON::CInputStream> input(std::static_pointer_cast<ADDON::CInputStream>(addons[i]));
      22. if (input->Supports(fileitem))
      23. {
      24. std::shared_ptr<ADDON::CInputStream> addon = input;
      25. if (!input->UseParent())
      26. addon = std::shared_ptr<ADDON::CInputStream>(new ADDON::CInputStream(*input));
      27. ADDON_STATUS status = addon->Create();
      28. if (status == ADDON_STATUS_OK)
      29. {
      30. unsigned int videoWidth, videoHeight;
      31. pPlayer->GetVideoResolution(videoWidth, videoHeight);
      32. addon->SetVideoResolution(videoWidth, videoHeight);
      33. return new CInputStreamAddon(fileitem, addon);
      34. }
      35. }
      36. }
      37. if (fileitem.IsDiscImage())
      38. {
      39. #ifdef HAVE_LIBBLURAY
      40. CURL url("udf://");
      41. url.SetHostName(file);
      42. url.SetFileName("BDMV/index.bdmv");
      43. if(XFILE::CFile::Exists(url.Get()))
      44. return new CDVDInputStreamBluray(pPlayer, fileitem);
      45. #endif
      46. return new CDVDInputStreamNavigator(pPlayer, fileitem);
      47. }
      48. #ifdef HAS_DVD_DRIVE
      49. if(file.compare(g_mediaManager.TranslateDevicePath("")) == 0)
      50. {
      51. #ifdef HAVE_LIBBLURAY
      52. if(XFILE::CFile::Exists(URIUtils::AddFileToFolder(file, "BDMV", "index.bdmv")))
      53. return new CDVDInputStreamBluray(pPlayer, fileitem);
      54. #endif
      55. return new CDVDInputStreamNavigator(pPlayer, fileitem);
      56. }
      57. #endif
      58. if (fileitem.IsDVDFile(false, true))
      59. return (new CDVDInputStreamNavigator(pPlayer, fileitem));
      60. else if(file.substr(0, 6) == "pvr://")
      61. return new CDVDInputStreamPVRManager(pPlayer, fileitem);
      62. #ifdef HAVE_LIBBLURAY
      63. else if (fileitem.IsType(".bdmv") || fileitem.IsType(".mpls") || file.substr(0, 7) == "bluray:")
      64. return new CDVDInputStreamBluray(pPlayer, fileitem);
      65. #endif
      66. else if(file.substr(0, 6) == "rtp://"
      67. || file.substr(0, 7) == "rtsp://"
      68. || file.substr(0, 6) == "sdp://"
      69. || file.substr(0, 6) == "udp://"
      70. || file.substr(0, 6) == "tcp://"
      71. || file.substr(0, 6) == "mms://"
      72. || file.substr(0, 7) == "mmst://"
      73. || file.substr(0, 7) == "mmsh://")
      74. return new CDVDInputStreamFFmpeg(fileitem);
      75. #ifdef ENABLE_DVDINPUTSTREAM_STACK
      76. else if(file.substr(0, 8) == "stack://")
      77. return new CDVDInputStreamStack(fileitem);
      78. #endif
      79. else if(file.substr(0, 7) == "rtmp://"
      80. || file.substr(0, 8) == "rtmpt://"
      81. || file.substr(0, 8) == "rtmpe://"
      82. || file.substr(0, 9) == "rtmpte://"
      83. || file.substr(0, 8) == "rtmps://")
      84. return new CDVDInputStreamFFmpeg(fileitem);
      85. CFileItem finalFileitem(fileitem);
      86. if (finalFileitem.IsInternetStream())
      87. {
      88. if (finalFileitem.ContentLookup())
      89. {
      90. CURL origUrl(finalFileitem.GetURL());
      91. XFILE::CCurlFile curlFile;
      92. // try opening the url to resolve all redirects if any
      93. try
      94. {
      95. if (curlFile.Open(finalFileitem.GetURL()))
      96. {
      97. CURL finalUrl(curlFile.GetURL());
      98. finalUrl.SetProtocolOptions(origUrl.GetProtocolOptions());
      99. finalUrl.SetUserName(origUrl.GetUserName());
      100. finalUrl.SetPassword(origUrl.GetPassWord());
      101. finalFileitem.SetPath(finalUrl.Get());
      102. }
      103. curlFile.Close();
      104. }
      105. catch (XFILE::CRedirectException *pRedirectEx)
      106. {
      107. if (pRedirectEx)
      108. {
      109. delete pRedirectEx->m_pNewFileImp;
      110. delete pRedirectEx;
      111. }
      112. }
      113. }
      114. if (finalFileitem.IsType(".m3u8"))
      115. return new CDVDInputStreamFFmpeg(finalFileitem);
      116. if (finalFileitem.GetMimeType() == "application/vnd.apple.mpegurl")
      117. return new CDVDInputStreamFFmpeg(finalFileitem);
      118. if (URIUtils::IsProtocol(finalFileitem.GetPath(), "udp"))
      119. return new CDVDInputStreamFFmpeg(finalFileitem);
      120. }
      121. // our file interface handles all these types of streams
      122. return (new CDVDInputStreamFile(finalFileitem));
      123. }

      其中很容易理解,kodi是一個(gè)全能的播放器,會(huì)支持許許多多的InputStream,根據(jù)類型判斷初始化什么播放器,而DVDInputStreamFFmpeg能獲取很多種類型的inputStream,下篇我們主要講高大上的DVDInputStreamDDmpeg。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多