Commit 69c3b24d by ziyue

优化遍历MediaSource接口性能

parent 4ec31165
......@@ -133,7 +133,8 @@ API_EXPORT void API_CALL mk_media_source_find(const char *schema,
void *user_data,
on_mk_media_source_find_cb cb);
//MediaSource::for_each_media()
API_EXPORT void API_CALL mk_media_source_for_each(void *user_data, on_mk_media_source_find_cb cb);
API_EXPORT void API_CALL mk_media_source_for_each(void *user_data, on_mk_media_source_find_cb cb, const char *schema,
const char *vhost, const char *app, const char *stream);
///////////////////////////////////////////HttpBody/////////////////////////////////////////////
//HttpBody对象的C映射
......
......@@ -238,11 +238,12 @@ API_EXPORT void API_CALL mk_media_source_find(const char *schema,
cb(user_data, src.get());
}
API_EXPORT void API_CALL mk_media_source_for_each(void *user_data, on_mk_media_source_find_cb cb){
API_EXPORT void API_CALL mk_media_source_for_each(void *user_data, on_mk_media_source_find_cb cb, const char *schema,
const char *vhost, const char *app, const char *stream) {
assert(cb);
MediaSource::for_each_media([&](const MediaSource::Ptr &src){
cb(user_data,src.get());
});
MediaSource::for_each_media([&](const MediaSource::Ptr &src) {
cb(user_data, src.get());
}, schema ? schema : "", vhost ? vhost : "", app ? app : "", stream ? stream : "");
}
///////////////////////////////////////////HttpBody/////////////////////////////////////////////
......
......@@ -483,21 +483,9 @@ void installWebApi() {
api_regist("/index/api/getMediaList",[](API_ARGS_MAP){
CHECK_SECRET();
//获取所有MediaSource列表
MediaSource::for_each_media([&](const MediaSource::Ptr &media){
if (!allArgs["schema"].empty() && allArgs["schema"] != media->getSchema()) {
return;
}
if (!allArgs["vhost"].empty() && allArgs["vhost"] != media->getVhost()) {
return;
}
if (!allArgs["app"].empty() && allArgs["app"] != media->getApp()) {
return;
}
if (!allArgs["stream"].empty() && allArgs["stream"] != media->getId()) {
return;
}
MediaSource::for_each_media([&](const MediaSource::Ptr &media) {
val["data"].append(makeMediaSourceJson(*media));
});
}, allArgs["schema"], allArgs["vhost"], allArgs["app"], allArgs["stream"]);
});
//测试url http://127.0.0.1/index/api/isMediaOnline?schema=rtsp&vhost=__defaultVhost__&app=live&stream=obs
......@@ -551,22 +539,10 @@ void installWebApi() {
int count_hit = 0;
int count_closed = 0;
list<MediaSource::Ptr> media_list;
MediaSource::for_each_media([&](const MediaSource::Ptr &media){
if(!allArgs["schema"].empty() && allArgs["schema"] != media->getSchema()){
return;
}
if(!allArgs["vhost"].empty() && allArgs["vhost"] != media->getVhost()){
return;
}
if(!allArgs["app"].empty() && allArgs["app"] != media->getApp()){
return;
}
if(!allArgs["stream"].empty() && allArgs["stream"] != media->getId()){
return;
}
MediaSource::for_each_media([&](const MediaSource::Ptr &media) {
++count_hit;
media_list.emplace_back(media);
});
}, allArgs["schema"], allArgs["vhost"], allArgs["app"], allArgs["stream"]);
bool force = allArgs["force"].as<bool>();
for(auto &media : media_list){
......
......@@ -206,7 +206,18 @@ bool MediaSource::stopSendRtp(const string &ssrc) {
return listener->stopSendRtp(*this, ssrc);
}
void MediaSource::for_each_media(const function<void(const MediaSource::Ptr &src)> &cb) {
static void do_for_each(const function<void(const MediaSource::Ptr &src)> &cb, weak_ptr<MediaSource> &ptr){
auto src = ptr.lock();
if (src) {
cb(src);
}
}
void MediaSource::for_each_media(const function<void(const MediaSource::Ptr &src)> &cb,
const string &schema,
const string &vhost,
const string &app,
const string &stream) {
decltype(s_media_source_map) copy;
{
//拷贝s_media_source_map后再遍历,考虑到是高频使用的全局单例锁,并且在上锁时会执行回调代码
......@@ -216,13 +227,31 @@ void MediaSource::for_each_media(const function<void(const MediaSource::Ptr &src
}
for (auto &pr0 : copy) {
//遍历schema
if (!schema.empty() && pr0.first != schema) {
continue;
}
for (auto &pr1 : pr0.second) {
//遍历vhost
if (!vhost.empty() && pr1.first != vhost) {
continue;
}
for (auto &pr2 : pr1.second) {
for (auto &pr3 : pr2.second) {
auto src = pr3.second.lock();
if(src){
cb(src);
//遍历app
if (!app.empty() && pr2.first != app) {
continue;
}
if (!stream.empty()) {
//指定stream id, 那么不用遍历stream
auto it = pr2.second.find(stream);
if (it != pr2.second.end()) {
do_for_each(cb, it->second);
}
continue;
}
for (auto &pr3 : pr2.second) {
//未指定stream id, 遍历stream
do_for_each(cb, pr3.second);
}
}
}
......
......@@ -273,7 +273,11 @@ public:
// 异步查找流
static void findAsync(const MediaInfo &info, const std::shared_ptr<TcpSession> &session, const function<void(const Ptr &src)> &cb);
// 遍历所有流
static void for_each_media(const function<void(const Ptr &src)> &cb);
static void for_each_media(const function<void(const Ptr &src)> &cb,
const string &schema = "",
const string &vhost = "",
const string &app = "",
const string &stream = "");
// 从mp4文件生成MediaSource
static MediaSource::Ptr createFromMP4(const string &schema, const string &vhost, const string &app, const string &stream, const string &file_path = "", bool check_app = true);
......
......@@ -23,22 +23,6 @@ public:
CMD_media(){
_parser.reset(new OptionParser([](const std::shared_ptr<ostream> &stream,mINI &ini){
MediaSource::for_each_media([&](const MediaSource::Ptr &media){
if(!ini["schema"].empty() && ini["schema"] != media->getSchema()){
//筛选协议不匹配
return;
}
if(!ini["vhost"].empty() && ini["vhost"] != media->getVhost()){
//筛选虚拟主机不匹配
return;
}
if(!ini["app"].empty() && ini["app"] != media->getApp()){
//筛选应用名不匹配
return;
}
if(!ini["stream"].empty() && ini["stream"] != media->getId()){
//流id不匹配
return;
}
if(ini.find("list") != ini.end()){
//列出源
(*stream) << "\t"
......@@ -78,7 +62,7 @@ public:
},false);
});
}, ini["schema"], ini["vhost"], ini["app"], ini["stream"]);
}));
(*_parser) << Option('k', "kick", Option::ArgNone,nullptr,false, "踢出媒体源", nullptr);
(*_parser) << Option('l', "list", Option::ArgNone,nullptr,false, "列出媒体源", nullptr);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论