优化遍历MediaSource接口性能

This commit is contained in:
ziyue 2021-06-30 21:06:29 +08:00
parent 4ec311652a
commit 69c3b24d06
6 changed files with 51 additions and 56 deletions

View File

@ -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映射

View File

@ -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/////////////////////////////////////////////

View File

@ -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){

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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);