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: ...
随机推荐
- 论文笔记--PCN:Real-Time Rotation-Invariant Face Detection with Progressive Calibration Networks
关键词:rotation-invariant face detection, rotation-in-plane, coarse-to-fine 核心概括:该篇文章为中科院计算所智能信息处理重点实验室 ...
- Swift 3.0项目迁移的一些记录
刚执行完Convert后报错600+,真是令人奔溃. 之后重新编译,仔细分析后发现其实真实错误远没有那么多.最终实际修改到的错误也就几十个,而且其中某些还是同一种错误. 这个项目是一个供自己使用的浏览 ...
- Redis从入门到精通:中级篇
原文链接:http://www.cnblogs.com/xrq730/p/8944539.html,转载请注明出处,谢谢 本文目录 上一篇文章以认识Redis为主,写了Redis系列的第一篇,现在开启 ...
- Bootstrap3 代码-内联代码
通过 <code> 标签包裹内联样式的代码片段. For example, <section> should be wrapped as inline. For example ...
- JBOSS EAP实战(1)
JBOSS的诞生 1998年,在硅谷SUN公司的SAP实验室,一个年轻人正坐在电脑前面思考,然后写着什么东西.不,他没有在写程序,他在写辞呈.他正在做出人生的一个重大决定:他要辞掉在SUN的这份工作, ...
- Markdown语法及SublimeText下使用技巧
Markdown语法及SublimeText下使用技巧 0.缘起 最近因为一直在学习Sublime Text,所以也就顺便试用了一下ST对Markdown的支持.正好CSDN正在大力宣传新上线的Mar ...
- 项目部署、配置、查错常用到的Linux命令
一.常用命令 ls 显示文件或目录 -l 列出文件详细信息l(list) -a 列出当前目录下所有文件及目录,包括隐藏的a(all) ll 会列出该文件下的所有文件信息,包括隐藏的文件的文件详细信息, ...
- Dynamics CRM 安装CRM程序系统检查界面报未将对象引用设置到对象的实例的解决方法
今天在安装CRM的时候,在系统检查阶段遇到了如下的错误,咋看之下直接是懵逼的 但不要着急,界面上有两个按钮,一个是详细信息,一个是帮助,详细信息不用看了就那一行字也看不出什么,咱们点下帮助看看,定位到 ...
- 【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )
作者 : 韩曙亮 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/50824912 相关地址介绍 : -- Universal I ...
- foxit pdf强制页面视图所有情况都为'合适宽度'
在左边的书签点击时,有时明明已经设置为合适宽度,但foxit会自动给你变为'合适页面'.真是莫名其妙的设置.好在可以这样更改: