XBMC源代码分析 7:视频播放器(dvdplayer)-输入流(以libRTMP为例)
前文分析了XBMC的基本结构:
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; }
XBMC源代码分析 7:视频播放器(dvdplayer)-输入流(以libRTMP为例)的更多相关文章
- XBMC源代码分析 6:视频播放器(dvdplayer)-文件头(以ffmpeg为例)
XBMC分析系列文章: XBMC源代码分析 1:整体结构以及编译方法 XBMC源代码分析 2:Addons(皮肤Skin) XBMC源代码分析 3:核心部分(core)-综述 XBMC源代码分析 4: ...
- XBMC源代码分析 4:视频播放器(dvdplayer)-解码器(以ffmpeg为例)
XBMC分析系列文章: XBMC源代码分析 1:整体结构以及编译方法 XBMC源代码分析 2:Addons(皮肤Skin) XBMC源代码分析 3:核心部分(core)-综述 本文我们分析XBMC中视 ...
- XBMC源代码分析 3:核心部分(core)-综述
前文分析了XBMC的整体结构以及皮肤部分: XBMC源代码分析 1:整体结构以及编译方法 XBMC源代码分析 2:Addons(皮肤Skin) 本文以及以后的文章主要分析XBMC的VC工程中的源代码. ...
- XBMC源代码分析 2:Addons(皮肤Skin)
前文已经对XBMC源代码的整体架构进行了分析: XBMC源代码分析 1:整体结构以及编译方法 从这篇文章开始,就要对XBMC源代码进行具体分析了.首先先不分析其C++代码,分析一下和其皮肤相关的代码. ...
- LIRe 源代码分析 5:提取特征向量[以颜色布局为例]
===================================================== LIRe源代码分析系列文章列表: LIRe 源代码分析 1:整体结构 LIRe 源代码分析 ...
- 转:XBMC源代码分析
1:整体结构以及编译方法 XBMC(全称是XBOX Media Center)是一个开源的媒体中心软件.XBMC最初为Xbox而开发,可以运行在Linux.OSX.Windows.Android4.0 ...
- XBMC源代码分析 1:整体结构以及编译方法
XBMC(全称是XBOX Media Center)是一个开源的媒体中心软件.XBMC最初为Xbox而开发,可以运行在Linux.OSX.Windows.Android4.0系统.我自己下载了一个然后 ...
- 从源代码分析modelDriven拦截器和params拦截器和拦截器prepare 和paramsPrepareParamsStack拦截器栈(让你的Struts2代码更简洁——如何培养框架设计能力
源代码文件:Web App Libraries/struts2-core-2.3.15.3.jar/struts-default.xml 拦截器modelDriven: <interceptor ...
- XBMC源代码简析 5:视频播放器(dvdplayer)-解复用器(以ffmpeg为例)
XBMC分析系列文章: XBMC源代码分析 1:整体结构以及编译方法 XBMC源代码分析 2:Addons(皮肤Skin) XBMC源代码分析 3:核心部分(core)-综述 XBMC源代码分析 4: ...
随机推荐
- 关于spring定时任务被多次调用的问题
在项目开发中,难免会用到定时任务,如果你的项目中用了spring这个框架,那么恭喜你,你的定时任务的创建将变得无比简单. 代码中只需要一个 @Scheduled标签,然后配置对应的执行频率即可 pas ...
- 安装oracle时修改Linux版本问题
Linux安装Oracle报Checking operating system version must be redhat, SuSE, redhat, UnitedLinux or asianux ...
- machine learning 之 Neural Network 1
整理自Andrew Ng的machine learning课程week 4. 目录: 为什么要用神经网络 神经网络的模型表示 1 神经网络的模型表示 2 实例1 实例2 多分类问题 1.为什么要用神经 ...
- linux 3.10 缺页异常(TLB_invalid)通用处理框架
- RTMPdump(libRTMP)源代码分析 4: 连接第一步——握手(Hand Shake)
===================================================== RTMPdump(libRTMP) 源代码分析系列文章: RTMPdump 源代码分析 1: ...
- 【Unity3D】 Unity Chan项目分享
写在前面 之前的一个博文里分享了日本Unity酱的项目,如果大家有去仔细搜Unity酱的话,就会发现日本Unity官方还放出了一个更完整的Unity酱的项目,感觉被萌化了!(事实上,Unity日本经常 ...
- java获取ip的方式,注意多级代理的方式获取
public String getIP() { String clientIP = ServletActionContext.getRequest().getHeader("x-forwar ...
- 浅谈机器人控制与仿真设计----RDS和ROS
机器人控制.仿真或实验,主要由三个部分组成,机器人.环境和算法. 当然各部分又包含很多子部分和功能,这里主要以仿真为主,为了使得仿真结果能够直接应用到实际机器人上,这里分别以RDS和ROS对比介绍.h ...
- EBS技术开发之VPD策略
VPD (虚拟专用数据库的简称),主要作用是根据运行环境的上下文,隐式的添加条 件. 好处是在数据库层解决细粒度的角色权限访问,避免在中间层写大量代码:坏处 是数据屏蔽的逻辑太隐蔽了,对于分析查找问题 ...
- 使用github搭建网站
http://blog.csdn.net/pipisorry/article/details/51707366 使用github建站 github设计了Pages功能,允许用户自定义项目首页,用来替代 ...