锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / 流媒体开源技术 / live555任务调度代码分析
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883

live555任务调度代码分析

(抽象接口)                   (抽象接口)                                                       (非抽象接口)
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
};

doEventLoop函数分析

在例子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是为什么--------------------------------------------------------------------------------------------------------------------------------------!!!!!!!!!!!!!!!!!!!?????????????????
并且判断是否有触发函数

调度例子

  1. #include <iostream>  
  2. #include "BasicUsageEnvironment.hh"  
  3. using namespace std;  
  4. /** 
  5.  * 后台IO任务处理函数(包括socket) 
  6.  * 此处将数据输出到控制台 
  7.  */  
  8. void taskFun(void* clientData, int mask) {  
  9.     /** 
  10.      * 检查 
  11.      */  
  12.     do {  
  13.         if (mask & SOCKET_EXCEPTION) {  
  14.             cout << "IO Event:Oh,my god!" << endl;  
  15.             break;  
  16.         }  
  17.         if (mask & SOCKET_WRITABLE) {  
  18.             cout << "IO Event(Writable):" <<  (char*) clientData << endl;  
  19.         }  
  20.         if (mask & SOCKET_READABLE) {  
  21.             cout << "IO Event(Readable):" <<  (char*) clientData << endl;  
  22.         }  
  23.         sleep(1);  
  24.     } while (0);  
  25. }  
  26. /** 
  27.  * 触发事件回调函数 
  28.  */  
  29. void eventFun(void* clientData) {  
  30.     cout << "Event Trigger:" << (char*) clientData << endl;  
  31.     sleep(1);  
  32. }  
  33. /** 
  34.  * 延迟任务回调函数 
  35.  */  
  36. void delayedFun(void* clientData) {  
  37.     cout << "Delayed Task:" << (char*) clientData << endl;  
  38.     sleep(1);  
  39. }  
  40. int main(int argc, char* argv[]) {  
  41.     TaskScheduler* scheduler = BasicTaskScheduler::createNew();  
  42.     UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);  
  43.     char taskFunData[] = "do task...";  
  44.     /** 
  45.      * 触发事件测试 
  46.      */  
  47.     EventTriggerId id = scheduler->createEventTrigger(&eventFun);  
  48.     if ((id & ~0) == 0) {  
  49.         cout << "Create Event Trigger Failed.\n";  
  50.     } else {  
  51.         /** 
  52.          * 将其加入调度队列 
  53.          * 不要被名字迷惑了 
  54.          * 这里仅仅是使其成为可调度状态,并不是立即执行 
  55.          * 以便doEventLoop()执行它 
  56.          */  
  57.         scheduler->triggerEvent(id, (void*) taskFunData);                           ---------------------------------------------------设置触发事件
  58.     }  
  59.     /** 
  60.      * 测试后台IO任务 
  61.      */  
  62.     scheduler->setBackgroundHandling(STDOUT_FILENO, SOCKET_WRITABLE, &taskFun,  -----------------------------------------------------设置socket处理函数,掩码
  63.             (void*) taskFunData);  
  64.     /** 
  65.      * 延迟任务测试 
  66.      * 延迟5秒后执行 
  67.      */  
  68.     scheduler->scheduleDelayedTask(5000000, delayedFun, (void*) taskFunData);  ------------------------------------------------------------延时函数设置
  69.     /** 
  70.      * 启动任务调度 
  71.      */  
  72.     env->taskScheduler().doEventLoop();  
  73.     return 0;  
  74. }  

相关解释

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,解码媒体信息,将传输过来的音视频信息分别进行解码;

6,播放显示,播放声音需要有扬声器,显示视频需要用显卡。
友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内