`

XBMC源代码分析 7:视频播放器(dvdplayer)-输入流(以libRTMP为例)

    博客分类:
  • XBMC
 
阅读更多

前文分析了XBMC的基本结构:

 

XBMC源代码分析 1:整体结构以及编译方法

XBMC源代码分析 2:Addons(皮肤Skin)

XBMC源代码分析 3:核心部分(core)-综述

XBMC源代码分析 4:视频播放器(dvdplayer)-解码器(以ffmpeg为例)

XBMC源代码简析 5:视频播放器(dvdplayer)-解复用器(以ffmpeg为例)

XBMC源代码分析 6:视频播放器(dvdplayer)-文件头(以ffmpeg为例)

本文我们分析XBMC中视频播放器(dvdplayer)中的输入流部分。由于输入流种类很多,因此以RTMP输入流为例进行分析。

XBMC中输入流部分文件目录结构如下图所示。

从目录中文件的名称我们可以看出,XBMC支持多种输入方式:File,HTSP,HTTP,RTMP等等。在这里我们看看RTMP部分的源代码。对应DVDInputStreamRTMP.h和DVDInputStreamRTMP.cpp

先来看看DVDInputStreamRTMP.h

 

/* 
 * 雷霄骅 
 * leixiaohua1020@126.com 
 * 中国传媒大学/数字电视技术 
 * 
 */ 
//如果有libRTMP
#ifdef HAS_LIBRTMP

#include "DVDInputStream.h"
#include "DllLibRTMP.h"
//支持RTMP输入流的类,继承CDVDInputStream
class CDVDInputStreamRTMP 
  : public CDVDInputStream
  , public CDVDInputStream::ISeekTime
{
public:
  CDVDInputStreamRTMP();
  virtual ~CDVDInputStreamRTMP();
  virtual bool    Open(const char* strFile, const std::string &content);//打开
  virtual void    Close();//关闭
  virtual int     Read(uint8_t* buf, int buf_size);//读取
  virtual int64_t Seek(int64_t offset, int whence);//跳转到
  bool            SeekTime(int iTimeInMsec);
  virtual bool Pause(double dTime);//暂停
  virtual bool    IsEOF();
  virtual int64_t GetLength();

  CCriticalSection m_RTMPSection;

protected:
  bool       m_eof;
  bool       m_bPaused;
  char*      m_sStreamPlaying;
  std::vector<CStdString> m_optionvalues;

  RTMP       *m_rtmp;
  DllLibRTMP m_libRTMP;
};

#endif



 


该类中包含了Open(),Close(),Read(),Seek(),Pause() 这类的方法。实现了对RTMP协议的各种操作。这些方法都是CDVDInputStreamRTMP父类CDVDInputStream中的方法。可以看一下CDVDInputStream的定义,就知道了。

 

 

//输入流类
class CDVDInputStream
{
public:
  class IChannel
  {
    public:
    virtual ~IChannel() {};
    virtual bool NextChannel(bool preview = false) = 0;
    virtual bool PrevChannel(bool preview = false) = 0;
    virtual bool SelectChannelByNumber(unsigned int channel) = 0;
    virtual bool SelectChannel(const PVR::CPVRChannel &channel) { return false; };
    virtual bool GetSelectedChannel(PVR::CPVRChannelPtr&) { return false; };
    virtual bool UpdateItem(CFileItem& item) = 0;
    virtual bool CanRecord() = 0;
    virtual bool IsRecording() = 0;
    virtual bool Record(bool bOnOff) = 0;
    virtual bool CanPause() = 0;
    virtual bool CanSeek() = 0;
  };

  class IDisplayTime
  {
    public:
    virtual ~IDisplayTime() {};
    virtual int GetTotalTime() = 0;
    virtual int GetTime() = 0;
  };

  class ISeekTime
  {
    public:
    virtual ~ISeekTime() {};
    virtual bool SeekTime(int ms) = 0;
  };

  class IChapter
  {
    public:
    virtual ~IChapter() {};
    virtual int  GetChapter() = 0;
    virtual int  GetChapterCount() = 0;
    virtual void GetChapterName(std::string& name) = 0;
    virtual bool SeekChapter(int ch) = 0;
  };

  class IMenus
  {
    public:
    virtual ~IMenus() {};
    virtual void ActivateButton() = 0;
    virtual void SelectButton(int iButton) = 0;
    virtual int  GetCurrentButton() = 0;
    virtual int  GetTotalButtons() = 0;
    virtual void OnUp() = 0;
    virtual void OnDown() = 0;
    virtual void OnLeft() = 0;
    virtual void OnRight() = 0;
    virtual void OnMenu() = 0;
    virtual void OnBack() = 0;
    virtual void OnNext() = 0;
    virtual void OnPrevious() = 0;
    virtual bool OnMouseMove(const CPoint &point) = 0;
    virtual bool OnMouseClick(const CPoint &point) = 0;
    virtual bool IsInMenu() = 0;
    virtual void SkipStill() = 0;
    virtual double GetTimeStampCorrection() = 0;
    virtual bool GetState(std::string &xmlstate) = 0;
    virtual bool SetState(const std::string &xmlstate) = 0;

  };

  class ISeekable
  {
    public:
    virtual ~ISeekable() {};
    virtual bool CanSeek()  = 0;
    virtual bool CanPause() = 0;
  };

  enum ENextStream
  {
    NEXTSTREAM_NONE,
    NEXTSTREAM_OPEN,
    NEXTSTREAM_RETRY,
  };

  CDVDInputStream(DVDStreamType m_streamType);
  virtual ~CDVDInputStream();
  virtual bool Open(const char* strFileName, const std::string& content);//打开
  virtual void Close() = 0;//关闭
  virtual int Read(uint8_t* buf, int buf_size) = 0;//读取
  virtual int64_t Seek(int64_t offset, int whence) = 0;//跳转
  virtual bool Pause(double dTime) = 0;//暂停
  virtual int64_t GetLength() = 0;
  virtual std::string& GetContent() { return m_content; };
  virtual std::string& GetFileName() { return m_strFileName; }
  virtual CURL &GetURL() { return m_url; }
  virtual ENextStream NextStream() { return NEXTSTREAM_NONE; }
  virtual void Abort() {}
  virtual int GetBlockSize() { return 0; }
  virtual void ResetScanTimeout(unsigned int iTimeoutMs) { }

  /*! \brief Indicate expected read rate in bytes per second.
   *  This could be used to throttle caching rate. Should
   *  be seen as only a hint
   */
  virtual void SetReadRate(unsigned rate) {}

  /*! \brief Get the cache status
   \return true when cache status was succesfully obtained
   */
  virtual bool GetCacheStatus(XFILE::SCacheStatus *status) { return false; }

  bool IsStreamType(DVDStreamType type) const { return m_streamType == type; }
  virtual bool IsEOF() = 0;
  virtual BitstreamStats GetBitstreamStats() const { return m_stats; }

  void SetFileItem(const CFileItem& item);

protected:
  DVDStreamType m_streamType;
  std::string m_strFileName;
  CURL m_url;
  BitstreamStats m_stats;
  std::string m_content;
  CFileItem m_item;
};



 


回到CDVDInputStreamRTMP类本身。可以看一下Open(),Close(),Read(),Seek(),Pause()这些方法的函数体。这些方方通过调用libRTMP中相应的方法,完成了对RTMP流媒体的各种操作。

 

 

/* 
 * 雷霄骅 
 * leixiaohua1020@126.com 
 * 中国传媒大学/数字电视技术 
 * 
 */ 
//打开
bool CDVDInputStreamRTMP::Open(const char* strFile, const std::string& content)
{
  if (m_sStreamPlaying)
  {
    free(m_sStreamPlaying);
    m_sStreamPlaying = NULL;
  }

  if (!CDVDInputStream::Open(strFile, "video/x-flv"))
    return false;

  CSingleLock lock(m_RTMPSection);

  // libRTMP can and will alter strFile, so take a copy of it
  m_sStreamPlaying = (char*)calloc(strlen(strFile)+1,sizeof(char));
  strcpy(m_sStreamPlaying,strFile);
  //libRTMP中的设置URL
  if (!m_libRTMP.SetupURL(m_rtmp, m_sStreamPlaying))
    return false;

  // SetOpt and SetAVal copy pointers to the value. librtmp doesn't use the values until the Connect() call,
  // so value objects must stay allocated until then. To be extra safe, keep the values around until Close(),
  // in case librtmp needs them again.
  m_optionvalues.clear();
  for (int i=0; options[i].name; i++)
  {
    CStdString tmp = m_item.GetProperty(options[i].name).asString();
    if (!tmp.empty())
    {
      m_optionvalues.push_back(tmp);
      AVal av_tmp;
      SetAVal(av_tmp, m_optionvalues.back());
      m_libRTMP.SetOpt(m_rtmp, &options[i].key, &av_tmp);
    }
  }
  //建立RTMP链接中的NetConnection和NetStream
  if (!m_libRTMP.Connect(m_rtmp, NULL) || !m_libRTMP.ConnectStream(m_rtmp, 0))
    return false;

  m_eof = false;

  return true;
}
//关闭
// close file and reset everything
void CDVDInputStreamRTMP::Close()
{
  CSingleLock lock(m_RTMPSection);
  CDVDInputStream::Close();
  //关闭连接
  m_libRTMP.Close(m_rtmp);

  m_optionvalues.clear();
  m_eof = true;
  m_bPaused = false;
}
//读取
int CDVDInputStreamRTMP::Read(uint8_t* buf, int buf_size)
{//读取
  int i = m_libRTMP.Read(m_rtmp, (char *)buf, buf_size);
  if (i < 0)
    m_eof = true;

  return i;
}
//跳转到
int64_t CDVDInputStreamRTMP::Seek(int64_t offset, int whence)
{
  if (whence == SEEK_POSSIBLE)
    return 0;
  else
    return -1;
}
//暂停
bool CDVDInputStreamRTMP::Pause(double dTime)
{
  CSingleLock lock(m_RTMPSection);

  m_bPaused = !m_bPaused;

  CLog::Log(LOGNOTICE, "RTMP Pause %s requested", m_bPaused ? "TRUE" : "FALSE");

  m_libRTMP.Pause(m_rtmp, m_bPaused);

  return true;
}



 

 

 

分享到:
评论

相关推荐

    repository.xbmc-addons-chinese-1.2.1.zip

    标题“repository.xbmc-addons-chinese-1.2.1.zip”揭示了这是一个与XBMC(Xbox Media Center)相关的软件资源包,版本号为1.2.1,并且是针对中文用户定制的。XBMC是一款开源的媒体中心软件,后来更名为Kodi,允许...

    script.bluray.com:用于访问 blu-ray.com 功能的 Kodi (XBMC) 插件

    script.bluray.com用于访问 blu-ray.com 功能的 Kodi (XBMC) 插件它目前仅在我的可用。 存储库的安装应通过 Kodi System::Settings::Add-ons::Install from zip 文件完成插件的安装应通过 Kodi System::Settings::...

    repository.xbmc-addons-chinese-2.0.0.zip

    标题中的"repository.xbmc-addons-chinese-2.0.0.zip"是一个针对KODI媒体中心的中文插件库的压缩包,版本号为2.0.0。这个压缩包包含了多款专为中国用户设计的KODI插件,旨在提升KODI在中文环境下的用户体验和功能...

    ru:seppius-xbmc-repo(叉子)

    【标题】"ru:seppius-xbmc-repo(叉子)" 指的是一种基于XBMC或Kodi的俄罗斯开发者论坛扩展资源库的克隆版本。XBMC(Xbox Media Center)是一个开源的媒体中心软件,后来更名为Kodi,它允许用户组织和播放各种多媒体...

    xbmc-forum:XBMC论坛的源代码-Forum source code

    "xbmc-forum:XBMC论坛的源代码"这个标题表明我们讨论的是XBMC官方论坛的源代码,这意味着我们可以深入理解其背后的开发过程、社区互动机制以及论坛的构建方式。 源代码通常对开发者来说是非常宝贵的资源,因为它...

    XBMC-OBD2:XBMC OBD2 插件-开源

    XBMC-OBD2 是一款基于XBMC(Xbox Media Center,现称为Kodi)平台的开源插件,专为汽车爱好者设计,它允许用户通过ELM327兼容的OBD2诊断适配器获取车辆的实时数据。下面将详细阐述这款插件的功能、工作原理以及如何...

    kodi中文插件最新2022 repository.xbmc-addons-chinese-2.0.0

    kodi中文插件最新2022 repository.xbmc-addons-chinese-2.0.0

    xbmc 移植到ANDROID 方法

    XBMC(Xbox Media Center)是一款开源媒体播放器应用,最初为Xbox游戏机开发,后来被移植到了多个操作系统上,包括Android。将XBMC移植到Android平台上需要进行一系列准备工作,包括设置Android开发环境、获取源代码...

    repository.xbmc-addons-chinese-2.0.1.zip亲测可用kodi中文插件库下载

    标题中的“repository.xbmc-addons-chinese-2.0.1.zip”是一个针对Kodi的中文插件库的压缩包,版本号为2.0.1。Kodi是一款开源的媒体中心软件,允许用户在各种设备上管理和播放多媒体内容,如视频、音乐和图片。这个...

    aac-rtmp-red5

    这个命令会将输入的MP3文件转换为AAC音频流,并推送到Red5服务器的指定流中。 总结一下,"aac-rtmp-red5"涉及的关键技术点包括:AAC音频编码、RTMP协议、Red5流媒体服务器的部署与配置、以及使用rtmpdump或FFmpeg等...

    XBMC-Trailer-Downloader:抓取 hd-trailers.net 并下载用于 XBMC 和 Cinema Experience 脚本的预告片

    XBMC-Trailer-Downloader 抓取 hd-trailers.net 并下载用于 XBMC 和 Cinema Experience 脚本的预告片。 安装:pip install -r requirements.txt 可以以 480/720/1080 的分辨率下载预告片。 可以删除已下载且超过...

    repository.kodi-chinese-addons:repository.kodi-chinese-addons xbmckodi用于中文插件的存储库

    这意味着用户将获得最新的插件和更新,开发者可以在这里找到最新的源代码以进行维护和开发。 通过这个仓库,Kodi用户可以轻松地安装和管理各种中文插件,比如: 1. **中文界面**:提供完全汉化的Kodi界面,让操作...

    xbmc-bilibili-main.zip

    在这个xbmc-bilibili-main插件中,Python被用来编写与Bilibili API进行交互的代码,实现视频搜索、播放、评论等功能。 安装此插件的步骤一般包括以下几步: 1. 下载"xbmc-bilibili-main.zip"文件到本地。 2. 在Kodi...

    kodi(xbmc)中文字幕插件

    在“repository.xbmc-addons-chinese”这个压缩包中,包含了一些为中国用户定制的Kodi插件,尤其是与中文字幕相关的插件。 安装插件的过程如下: 1. **打开Kodi**:启动你的Kodi应用程序,进入主界面。 2. **进入...

    XBMC-Streams:XBMC插件,用于观看视频流-开源

    XBMC插件,用于观看芬兰电视台的视频流。 YLE Areena和Ruutu可与Linux和Windows一起使用。 Katsomo仅在Windows中工作。 Katsomo使用Internet Explorer和Silverlight插件来显示视频。 大部分在Linux上进行了测试。 ...

    screensaver.plugin.slideshow:适用于Kodi(XBMC)的插件幻灯片屏幕保护程序插件-插件中的图像幻灯片

    适用于Kodi(XBMC)的插件幻灯片屏幕保护程序插件-插件中的图像幻灯片 此插件允许使用图片插件作为图片幻灯片屏幕保护程序的源。 安装应该通过Kodi System :: Settings :: Add-ons :: Get Add-Ons :: All Add-Ons :...

    Kodi-XBMC-plugin-boilerplate:目录结构,包含操作Kodi(XBMC)附加组件所需的所有资源

    Kodi(XBMC)插件样板 目录结构,包含操作Kodi(XBMC)附加组件所需的所有资源。 用法 。 解压缩并将文件夹“ plugin.media-type.plugin-name ”重命名为您的插件名称。 在您喜欢的Editor / IDE中将文件夹添加到...

    XBMC-Plugin-Songza:这是流行音乐网站 Songza.com 的 XBMC 插件

    1. 下载 XBMC-Plugin-Songza-master 压缩包,并解压到 XBMC 或 Kodi 的 "addons" 目录下的 "video" 或 "audio" 子目录,具体取决于你想将 Songza 作为音频源还是视频源。 2. 在 XBMC 或 Kodi 启动后,进入 "Program ...

    ubuntu下的kodi(XBMC)编译

    标题中的“ubuntu下的kodi(XBMC)编译”指的是在Ubuntu操作系统环境下,对Kodi(以前称为XBMC,Xbox Media Center)媒体中心软件进行源代码编译的过程。Kodi是一款开源的多媒体中心应用,它能播放各种音频、视频格式...

    xbmc-my-canal:XBMC法国运河+重播插件

    3. **播放器接口**:与XBMC的内置播放器集成,确保视频内容能流畅播放,同时处理流媒体技术和分辨率适应。 4. **用户界面**:设计一个直观的界面,让用户可以浏览、搜索和选择他们想看的内容,保持与XBMC的UI风格...

Global site tag (gtag.js) - Google Analytics