WebRTC中线程模型和常见线程模型介绍
WebRTC专题开嗨鸭 !!!
一、 WebRTC 线程模型
2、WebRTC网络PhysicalSocketServer之WSAEventselect模型使用
二、 WebRTC媒体协商
1、WebRTC媒体协商之SDP中JsepSessionDescription类结构分析
三、 WebRTC 音频数据采集
四、 WebRTC 音频引擎(编解码和3A算法)
五、 WebRTC 视频数据采集
六、 WebRTC 视频引擎( 编解码)
七、 WebRTC 网络传输
2、WebRTC的ICE之Dtls/SSL/TLSv1.x协议详解
八、 WebRTC服务质量(Qos)
3、WebRTC之NACK、RTX 在什么时机判断丢包发送NACK请求和RTX丢包重传
九、 NetEQ
十、 Simulcast与SVC
@TOC
</font>
<hr style=” border:solid; width:100px; height:1px;” color=#000000 size=1”>
前言
<font color=#999AAA >WebRTC是音视频行业的标杆, 如果要学习音视频, WebRTC是进入音视频行业最好方法, 里面可以有成熟方案, 例如:音频中3A 算法、网络评估、自适应码流、SVC等等 , 非常适和刚刚进入音视频行业小伙伴, 以后再音视频行业长期打算的小伙伴的学习项目。 里面有大量知识点 , 小伙伴们加油吧!!! 奔跑起来吧 ^_^ </font>
<hr style=” border:solid; width:100px; height:1px;” color=#000000 size=1”>
<font color=#999AAA >提示:以下是本篇文章正文内容,下面案例可供参考
一、WebRTC线程模式和常见线程模式
1、WebRTC线程模式
上图就是WebRTC中三大线程模式: 分别是网络线程、工作线程、信号线程
webrtc -> api
webrtc ->proxy
webrtc -> core
WebRTC中线程模型与对外接口非常有关系, 是封装SDK非常好的方法。 无论用户多少个线程访问最后都不会有线程安全的问题,这个与WebRTC架构有关系的WebRTC中写一个代理类
2、常见线程模型
常见线程模型就是任务队列中有任务就分配空闲线程去执行。
二、WebRTC线程模型源码走读
1、 Thread
rtc_base/thread.h
①、 任务放到队列中函数Post
是把任务放到任务队列中msgq_
<font color=#999AAA >代码如下(示例):
void MessageQueue::Post(const Location& posted_from,
MessageHandler* phandler,
uint32_t id,
MessageData* pdata,
bool time_sensitive) {
if (IsQuitting()) {
delete pdata;
return;
}
// Keep thread safe
// Add the message to the end of the queue
// Signal for the multiplexer to return
{
CritScope cs(&crit_);
Message msg;
msg.posted_from = posted_from;
msg.phandler = phandler;
msg.message_id = id;
msg.pdata = pdata;
if (time_sensitive) {
msg.ts_sensitive = TimeMillis() + kMaxMsgLatency;
}
msgq_.push_back(msg);
}
WakeUpSocketServer();
}
②、 执行任务接口 Dispatch
<font color=#999AAA >代码如下(示例):
bool Thread::ProcessMessages(int cmsLoop) {
// Using ProcessMessages with a custom clock for testing and a time greater
// than 0 doesn't work, since it's not guaranteed to advance the custom
// clock's time, and may get stuck in an infinite loop.
RTC_DCHECK(GetClockForTesting() == nullptr || cmsLoop == 0 ||
cmsLoop == kForever);
int64_t msEnd = (kForever == cmsLoop) ? 0 : TimeAfter(cmsLoop);
int cmsNext = cmsLoop;
while (true) {
#if defined(WEBRTC_MAC)
ScopedAutoReleasePool pool;
#endif
Message msg;
if (!Get(&msg, cmsNext))
return !IsQuitting();
Dispatch(&msg);
if (cmsLoop != kForever) {
cmsNext = static_cast<int>(TimeUntil(msEnd));
if (cmsNext < 0)
return true;
}
}
}
void MessageQueue::Dispatch(Message* pmsg) {
TRACE_EVENT2("webrtc", "MessageQueue::Dispatch", "src_file_and_line",
pmsg->posted_from.file_and_line(), "src_func",
pmsg->posted_from.function_name());
int64_t start_time = TimeMillis();
pmsg->phandler->OnMessage(pmsg);
int64_t end_time = TimeMillis();
int64_t diff = TimeDiff(end_time, start_time);
// 每个函数进行数据统计 那个函数执行时间比较长
if (diff >= kSlowDispatchLoggingThreshold) {
RTC_LOG(LS_INFO) << "Message took " << diff
<< "ms to dispatch. Posted from: "
<< pmsg->posted_from.ToString();
}
}
2、 WebRTC中线程切换 (SynchronousMethodCall)
①、使用信号量通知的
<font color=#999AAA >代码如下(示例):
class SynchronousMethodCall : public rtc::MessageData,
public rtc::MessageHandler {
public:
explicit SynchronousMethodCall(rtc::MessageHandler* proxy);
~SynchronousMethodCall() override;
void Invoke(const rtc::Location& posted_from, rtc::Thread* t);
private:
void OnMessage(rtc::Message*) override;
rtc::Event e_;
rtc::MessageHandler* proxy_;
};
SynchronousMethodCall::SynchronousMethodCall(rtc::MessageHandler* proxy)
: proxy_(proxy) {}
SynchronousMethodCall::~SynchronousMethodCall() = default;
void SynchronousMethodCall::Invoke(const rtc::Location& posted_from,
rtc::Thread* t) {
// 判断是否当前线程如果是当前线程就立即执行,如果不是就把任务放到任务队列中去然后唤醒线程,当前线程wait中
if (t->IsCurrent()) {
proxy_->OnMessage(nullptr);
} else {
t->Post(posted_from, this, 0);
e_.Wait(rtc::Event::kForever);
}
}
void SynchronousMethodCall::OnMessage(rtc::Message*) {
//执行任务
proxy_->OnMessage(nullptr);
//任务执行完成, 就唤醒线程 获取结果
e_.Set();
}
②、 WebRTC中线程同步绑定函数 MethodCall0
//C++中模版迟绑定多个参数的模版参数 非常有意思
template <typename R>
class ReturnType {
public:
template <typename C, typename M>
void Invoke(C* c, M m) {
r_ = (c->*m)();
}
template <typename C, typename M, typename T1>
void Invoke(C* c, M m, T1 a1) {
r_ = (c->*m)(std::move(a1));
}
template <typename C, typename M, typename T1, typename T2>
void Invoke(C* c, M m, T1 a1, T2 a2) {
r_ = (c->*m)(std::move(a1), std::move(a2));
}
template <typename C, typename M, typename T1, typename T2, typename T3>
void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) {
r_ = (c->*m)(std::move(a1), std::move(a2), std::move(a3));
}
template <typename C,
typename M,
typename T1,
typename T2,
typename T3,
typename T4>
void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3, T4 a4) {
r_ = (c->*m)(std::move(a1), std::move(a2), std::move(a3), std::move(a4));
}
template <typename C,
typename M,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
r_ = (c->*m)(std::move(a1), std::move(a2), std::move(a3), std::move(a4),
std::move(a5));
}
R moved_result() { return std::move(r_); }
private:
R r_;
};
template <typename C, typename R>
class MethodCall0 : public rtc::Message, public rtc::MessageHandler {
public:
typedef R (C::*Method)();
MethodCall0(C* c, Method m) : c_(c), m_(m) {}
R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
internal::SynchronousMethodCall(this).Invoke(posted_from, t);
return r_.moved_result();
}
private:
void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
C* c_;
Method m_;
ReturnType<R> r_; // 绑定函数和返回值
};
总结
<font color=#999AAA > WebRTC中线程模型主要是做线程安全方案
-
上一页
H264视频GOP组和视频压缩技术之有损压缩(帧间压缩、帧内压缩)、无损压缩(ACBAC压缩) -
下一页
WebRTC网络PhysicalSocketServer之WSAEventselect模型使用