
精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
(抽象接口) (抽象接口) (非抽象接口)
class TaskScheduler -----------------派生类BasicTaskScheduler0(重新定义了socket事件处理函数)------------派生类BasicTaskScheduler(主要定义了setBackgroundHandling,SingleStep)
class UsageEnvironment -----------------------------------------包含TaskScheduler成员
typedef void TaskFunc(void* clientData);
class TaskScheduler {
public:
virtual TaskTokenscheduleDelayedTask(int64_t microseconds, TaskFunc* proc,void* clientData) = 0;
// Schedules a task to occur (after a delay) when we next
// reach a scheduling point.-------------------------------------------------------------------------------------------------------------------------------在特定情况下调用任务proc
// For handling socket operations in the background (from the event loop):
typedef void BackgroundHandlerProc(void* clientData, int mask);--------------------------------------------------------------------------------在后台处理socket操作,传递到setBackgroundHandling
// Possible bits to set in "mask". (These are deliberately defined
// the same as those in Tcl, to make a Tcl-based subclass easy.)
#define SOCKET_READABLE (1<<1)-------------------------------------------------------------------------------------------------------------掩码 (用来判断当前关心的操作)
#define SOCKET_WRITABLE (1<<2)
#define SOCKET_EXCEPTION (1<<3)
virtual void setBackgroundHandling(int socketNum, int conditionSet, BackgroundHandlerProc* handlerProc, void* clientData) = 0;
void disableBackgroundHandling(int socketNum) { setBackgroundHandling(socketNum, 0, NULL, NULL); }
virtual void moveSocketHandling(int oldSocketNum, int newSocketNum) = 0;
// Changes any socket handling for "oldSocketNum" so that occurs with "newSocketNum" instead.
protected:
TaskScheduler(); // abstract base class
};
在例子testH264VideoStreamer.cpp中env->taskScheduler().doEventLoop(),env是UsageEnvironment 类 ,taskScheduler().doEventLoop调用了doEventLoop
在taskScheduler的派生类BasicTaskScheduler0中定义了次函数
void BasicTaskScheduler0::doEventLoop(char volatile* watchVariable) {
// Repeatedly loop, handling readble sockets and timed events:
while (1) {
if (watchVariable != NULL && *watchVariable != 0) break;
SingleStep();
}
SingleStep函数在BasicTaskScheduler定义了
void BasicTaskScheduler::SingleStep(unsigned maxDelayTime) {
此函数中调用select(fMaxNumSockets, &readSet, &writeSet, &exceptionSet, &tv_timeToDelay);--------------------------------------------------------------------------select函数,大家是不是很熟悉,再此如果返回就处理套接字接收的数据流
(此处select返回判断小于0,这tm是为什么--------------------------------------------------------------------------------------------------------------------------------------!!!!!!!!!!!!!!!!!!!?????????????????
并且判断是否有触发函数
class HandlerDescriptor {-------------------------------------------------------------------------------------------------------双向链表节点,每一个对应一个socketnum,处理函数
class HandlerSet -------------------------------------------------------------------------------------------------------包含了针对HandlerDescriptor 处理函数的设置、查找
class HandlerIterator --------------------------------------------------------------------------------------------------------是HandlerDescriptor 指示器,用来遍历HandlerDescriptor
环境抽象类
UsageEnvironment------------派生类BasicUsageEnvironment0-------------------派生类BasicUsageEnvironment主要定义了处理函数错误的函数,包含了一个TaskScheduler任务调度类
我们都知道播放流媒体有几个必要步骤:
1,获取原始媒体信息(音频、视频),该步要有相应的设备,如摄像头和麦克风;------------------------------------海思 264 avi ,传输视频全是h264吗??????????
2,编码媒体信息,大家可以用ffmpeg编码,也可以用其他开源的程序,比如libaac,;
3,传输编码压缩好的媒体信息,如采用http、rtsp/rtp、rtmp、rtmfp、hls等协议;
4,接受媒体信息,此时将会获取到传输过来的音频和视频信息;
5,解码媒体信息,将传输过来的音视频信息分别进行解码;