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: ...
随机推荐
- centos 7 安装nvidia显卡驱动
How to install Nvidia drivers in CentOS 7 - Tutorial : http://www.dedoimedo.com/computers/centos-7- ...
- JDBC:从原理到应用
一.是为何物 1.概念 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用J ...
- windows资源管理器中配置右键bash here
windows下安装了git后有git bash here 但是安装了cygwin没有bash here 我们可以通过修改注册表的方式自己做一个 Win10下在注册表内有一般有两个默认的 cmd 和 ...
- Node.js Buffer(缓冲区)
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型. 但在处理像TCP流或文件流时,必须使用到二进制数据.因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门 ...
- ToolBar控件详解
ToolBar控件详解 在Activity中添加ToolBar 1.添加库 dependencies { ... compile "com.android.support:appcompat ...
- [OpenCV] Write & Read files
例如写 KeyPoint向量,以及他的描述矩阵. // ... vector<KeyPoint> key_points; Mat descriptors; // ... fs.open(o ...
- Core Python Programming一书中关于深浅拷贝的错误
该书关于深浅拷贝的论述: 6.20. *Copying Python Objects and Shallow and Deep Copies "when shallow copies are ...
- Redis 学习笔记1:CentOS 6.7下安装Redis
在linux环境搭建Redis环境,首先从官网(http://redis.io/)下载Redis 版本,本人使用的3.21版本. 1. 将redis 解压到 /usr/local目录下. [root ...
- 通过grub-install命令把grub安装到u盘
通过grub-install命令把grub安装到u盘 ①准备一个u盘,容量不限,能有1MB都足够了. ②把u盘格式化(我把u盘格式化成FAT.fat32格式了,最后证明也是成功的).③开启linux系 ...
- 我的第一个RootKit,支持XP、Vista、Win7、Win8 RTM 32位
只有写过一个BootKit,才能比较深刻的理解其整个过程与机制,也能加深对Windows系统引导各个过程的熟悉和理解. 我写的这个bootkit,暂时还没想到一个比较好的名字,它 1. 支持xp到w ...