 
   精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
(抽象接口)                   (抽象接口)                                                        (非抽象接口) 
          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,解码媒体信息,将传输过来的音视频信息分别进行解码;