config.cpp 12.9 KB
Newer Older
xiongziliang committed
1
/*
xiongziliang committed
2
 * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
xiongziliang committed
3
 *
4
 * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
xiongziliang committed
5
 *
xiongziliang committed
6 7 8
 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
xiongziliang committed
9 10
 */

xiongziliang committed
11
#include "Common/config.h"
xzl committed
12
#include "Util/util.h"
13
#include "Util/logger.h"
xzl committed
14
#include "Util/onceToken.h"
15
#include "Util/NoticeCenter.h"
xzl committed
16 17
#include "Network/sockutil.h"

xiongziliang committed
18
using namespace toolkit;
xzl committed
19

xiongziliang committed
20
namespace mediakit {
xzl committed
21

22 23
bool loadIniConfig(const char *ini_path){
    string ini;
24
    if(ini_path && ini_path[0] != '\0'){
25 26 27 28
        ini = ini_path;
    }else{
        ini = exePath() + ".ini";
    }
29
    try{
30
        mINI::Instance().parseFile(ini);
31
        NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastReloadConfig);
32
        return true;
33
    }catch (std::exception &) {
34
        InfoL << "dump ini file to:" << ini;
35 36
        mINI::Instance().dumpFile(ini);
        return false;
37
    }
xiongziliang committed
38
}
xzl committed
39 40
////////////广播名称///////////
namespace Broadcast {
41 42
const string kBroadcastMediaChanged = "kBroadcastMediaChanged";
const string kBroadcastRecordMP4 = "kBroadcastRecordMP4";
43
const string kBroadcastRecordTs = "kBroadcastRecoredTs";
44 45 46 47 48 49 50 51 52 53 54
const string kBroadcastHttpRequest = "kBroadcastHttpRequest";
const string kBroadcastHttpAccess = "kBroadcastHttpAccess";
const string kBroadcastOnGetRtspRealm = "kBroadcastOnGetRtspRealm";
const string kBroadcastOnRtspAuth = "kBroadcastOnRtspAuth";
const string kBroadcastMediaPlayed = "kBroadcastMediaPlayed";
const string kBroadcastMediaPublish = "kBroadcastMediaPublish";
const string kBroadcastFlowReport = "kBroadcastFlowReport";
const string kBroadcastReloadConfig = "kBroadcastReloadConfig";
const string kBroadcastShellLogin = "kBroadcastShellLogin";
const string kBroadcastNotFoundStream = "kBroadcastNotFoundStream";
const string kBroadcastStreamNoneReader = "kBroadcastStreamNoneReader";
55
const string kBroadcastHttpBeforeAccess = "kBroadcastHttpBeforeAccess";
56
} //namespace Broadcast
57

58 59 60
//通用配置项目
namespace General{
#define GENERAL_FIELD "general."
61
const string kMediaServerId = GENERAL_FIELD"mediaServerId";
62 63 64 65
const string kFlowThreshold = GENERAL_FIELD"flowThreshold";
const string kStreamNoneReaderDelayMS = GENERAL_FIELD"streamNoneReaderDelayMS";
const string kMaxStreamWaitTimeMS = GENERAL_FIELD"maxStreamWaitMS";
const string kEnableVhost = GENERAL_FIELD"enableVhost";
66
const string kAddMuteAudio = GENERAL_FIELD"addMuteAudio";
67
const string kResetWhenRePlay = GENERAL_FIELD"resetWhenRePlay";
68 69
const string kPublishToHls = GENERAL_FIELD"publishToHls";
const string kPublishToMP4 = GENERAL_FIELD"publishToMP4";
xiongziliang committed
70
const string kMergeWriteMS = GENERAL_FIELD"mergeWriteMS";
71
const string kModifyStamp = GENERAL_FIELD"modifyStamp";
72 73 74 75 76
const string kHlsDemand = GENERAL_FIELD"hls_demand";
const string kRtspDemand = GENERAL_FIELD"rtsp_demand";
const string kRtmpDemand = GENERAL_FIELD"rtmp_demand";
const string kTSDemand = GENERAL_FIELD"ts_demand";
const string kFMP4Demand = GENERAL_FIELD"fmp4_demand";
77

78 79
onceToken token([](){
    mINI::Instance()[kFlowThreshold] = 1024;
xiongziliang committed
80 81
    mINI::Instance()[kStreamNoneReaderDelayMS] = 20 * 1000;
    mINI::Instance()[kMaxStreamWaitTimeMS] = 15 * 1000;
82
    mINI::Instance()[kEnableVhost] = 0;
83 84 85 86
    mINI::Instance()[kAddMuteAudio] = 1;
    mINI::Instance()[kResetWhenRePlay] = 1;
    mINI::Instance()[kPublishToHls] = 1;
    mINI::Instance()[kPublishToMP4] = 0;
87
    mINI::Instance()[kMergeWriteMS] = 0;
88
    mINI::Instance()[kModifyStamp] = 0;
xiongziliang committed
89
    mINI::Instance()[kMediaServerId] = makeRandStr(16);
90 91 92 93 94 95
    mINI::Instance()[kHlsDemand] = 0;
    mINI::Instance()[kRtspDemand] = 0;
    mINI::Instance()[kRtmpDemand] = 0;
    mINI::Instance()[kTSDemand] = 0;
    mINI::Instance()[kFMP4Demand] = 0;

96
},nullptr);
97 98

}//namespace General
xzl committed
99 100 101 102 103

////////////HTTP配置///////////
namespace Http {
#define HTTP_FIELD "http."
//http 文件发送缓存大小
104
const string kSendBufSize = HTTP_FIELD"sendBufSize";
xzl committed
105
//http 最大请求字节数
106
const string kMaxReqSize = HTTP_FIELD"maxReqSize";
xzl committed
107
//http keep-alive秒数
108
const string kKeepAliveSecond = HTTP_FIELD"keepAliveSecond";
xzl committed
109
//http 字符编码
110
const string kCharSet = HTTP_FIELD"charSet";
xzl committed
111
//http 服务器根目录
112
const string kRootPath = HTTP_FIELD"rootPath";
xzl committed
113
//http 404错误提示内容
114
const string kNotFound = HTTP_FIELD"notFound";
115 116
//是否显示文件夹菜单
const string kDirMenu = HTTP_FIELD"dirMenu";
xzl committed
117 118

onceToken token([](){
119 120 121
    mINI::Instance()[kSendBufSize] = 64 * 1024;
    mINI::Instance()[kMaxReqSize] = 4*1024;
    mINI::Instance()[kKeepAliveSecond] = 15;
122 123
    mINI::Instance()[kDirMenu] = true;

124
#if defined(_WIN32)
125
    mINI::Instance()[kCharSet] = "gb2312";
126
#else
127
    mINI::Instance()[kCharSet] ="utf-8";
128 129
#endif

130 131 132 133 134 135 136 137 138 139 140
    mINI::Instance()[kRootPath] = "./www";
    mINI::Instance()[kNotFound] =
                    "<html>"
                    "<head><title>404 Not Found</title></head>"
                    "<body bgcolor=\"white\">"
                    "<center><h1>您访问的资源不存在!</h1></center>"
                    "<hr><center>"
                    SERVER_NAME
                    "</center>"
                    "</body>"
                    "</html>";
xzl committed
141 142 143 144 145 146 147
},nullptr);

}//namespace Http

////////////SHELL配置///////////
namespace Shell {
#define SHELL_FIELD "shell."
148
const string kMaxReqSize = SHELL_FIELD"maxReqSize";
xzl committed
149 150

onceToken token([](){
151
    mINI::Instance()[kMaxReqSize] = 1024;
xzl committed
152 153 154 155 156 157
},nullptr);
} //namespace Shell

////////////RTSP服务器配置///////////
namespace Rtsp {
#define RTSP_FIELD "rtsp."
158 159 160
const string kAuthBasic = RTSP_FIELD"authBasic";
const string kHandshakeSecond = RTSP_FIELD"handshakeSecond";
const string kKeepAliveSecond = RTSP_FIELD"keepAliveSecond";
161 162
const string kDirectProxy = RTSP_FIELD"directProxy";

xzl committed
163
onceToken token([](){
164 165
    //默认Md5方式认证
    mINI::Instance()[kAuthBasic] = 0;
166 167
    mINI::Instance()[kHandshakeSecond] = 15;
    mINI::Instance()[kKeepAliveSecond] = 15;
168
    mINI::Instance()[kDirectProxy] = 1;
xzl committed
169 170 171 172 173 174
},nullptr);
} //namespace Rtsp

////////////RTMP服务器配置///////////
namespace Rtmp {
#define RTMP_FIELD "rtmp."
175 176 177
const string kModifyStamp = RTMP_FIELD"modifyStamp";
const string kHandshakeSecond = RTMP_FIELD"handshakeSecond";
const string kKeepAliveSecond = RTMP_FIELD"keepAliveSecond";
xzl committed
178 179

onceToken token([](){
180
    mINI::Instance()[kModifyStamp] = false;
181 182
    mINI::Instance()[kHandshakeSecond] = 15;
    mINI::Instance()[kKeepAliveSecond] = 15;
xzl committed
183 184 185 186 187 188 189 190
},nullptr);
} //namespace RTMP


////////////RTP配置///////////
namespace Rtp {
#define RTP_FIELD "rtp."
//RTP打包最大MTU,公网情况下更小
191 192
const string kVideoMtuSize = RTP_FIELD"videoMtuSize";
const string kAudioMtuSize = RTP_FIELD"audioMtuSize";
xzl committed
193
//RTP排序缓存最大个数
194
const string kMaxRtpCount = RTP_FIELD"maxRtpCount";
xzl committed
195
//如果RTP序列正确次数累计达到该数字就启动清空排序缓存
196
const string kClearCount = RTP_FIELD"clearCount";
xzl committed
197 198

onceToken token([](){
199 200 201 202
    mINI::Instance()[kVideoMtuSize] = 1400;
    mINI::Instance()[kAudioMtuSize] = 600;
    mINI::Instance()[kMaxRtpCount] = 50;
    mINI::Instance()[kClearCount] = 10;
xzl committed
203 204 205 206 207 208 209
},nullptr);
} //namespace Rtsp

////////////组播配置///////////
namespace MultiCast {
#define MULTI_FIELD "multicast."
//组播分配起始地址
210
const string kAddrMin = MULTI_FIELD"addrMin";
xzl committed
211
//组播分配截止地址
212
const string kAddrMax = MULTI_FIELD"addrMax";
xzl committed
213
//组播TTL
214
const string kUdpTTL = MULTI_FIELD"udpTTL";
xzl committed
215 216

onceToken token([](){
217 218 219
    mINI::Instance()[kAddrMin] = "239.0.0.0";
    mINI::Instance()[kAddrMax] = "239.255.255.255";
    mINI::Instance()[kUdpTTL] = 64;
xzl committed
220 221 222 223 224 225 226
},nullptr);
} //namespace MultiCast

////////////录像配置///////////
namespace Record {
#define RECORD_FIELD "record."
//查看录像的应用名称
227
const string kAppName = RECORD_FIELD"appName";
xzl committed
228
//每次流化MP4文件的时长,单位毫秒
229
const string kSampleMS = RECORD_FIELD"sampleMS";
230
//MP4文件录制大小,默认一个小时
231
const string kFileSecond = RECORD_FIELD"fileSecond";
xzl committed
232
//录制文件路径
233
const string kFilePath = RECORD_FIELD"filePath";
234 235
//mp4文件写缓存大小
const string kFileBufSize = RECORD_FIELD"fileBufSize";
236 237
//mp4录制完成后是否进行二次关键帧索引写入头部
const string kFastStart = RECORD_FIELD"fastStart";
Weiwei.Zhou committed
238 239 240
//mp4文件是否重头循环读取
const string kFileRepeat = RECORD_FIELD"fileRepeat";

xzl committed
241
onceToken token([](){
242 243 244 245 246 247 248
    mINI::Instance()[kAppName] = "record";
    mINI::Instance()[kSampleMS] = 500;
    mINI::Instance()[kFileSecond] = 60*60;
    mINI::Instance()[kFilePath] = "./www";
    mINI::Instance()[kFileBufSize] = 64 * 1024;
    mINI::Instance()[kFastStart] = false;
    mINI::Instance()[kFileRepeat] = false;
xzl committed
249 250 251 252 253 254 255
},nullptr);
} //namespace Record

////////////HLS相关配置///////////
namespace Hls {
#define HLS_FIELD "hls."
//HLS切片时长,单位秒
256
const string kSegmentDuration = HLS_FIELD"segDur";
xzl committed
257
//HLS切片个数
258
const string kSegmentNum = HLS_FIELD"segNum";
259 260
//HLS切片从m3u8文件中移除后,继续保留在磁盘上的个数
const string kSegmentRetain = HLS_FIELD"segRetain";
xzl committed
261
//HLS文件写缓存大小
262
const string kFileBufSize = HLS_FIELD"fileBufSize";
xzl committed
263
//录制文件路径
264
const string kFilePath = HLS_FIELD"filePath";
265 266
// 是否广播 ts 切片完成通知
const string kBroadcastRecordTs = HLS_FIELD"broadcastRecordTs";
xzl committed
267 268

onceToken token([](){
269 270 271 272 273
    mINI::Instance()[kSegmentDuration] = 2;
    mINI::Instance()[kSegmentNum] = 3;
    mINI::Instance()[kSegmentRetain] = 5;
    mINI::Instance()[kFileBufSize] = 64 * 1024;
    mINI::Instance()[kFilePath] = "./www";
274
    mINI::Instance()[kBroadcastRecordTs] = false;
xzl committed
275 276 277
},nullptr);
} //namespace Hls

278 279 280 281 282 283 284 285 286 287

////////////Rtp代理相关配置///////////
namespace RtpProxy {
#define RTP_PROXY_FIELD "rtp_proxy."
//rtp调试数据保存目录
const string kDumpDir = RTP_PROXY_FIELD"dumpDir";
//rtp接收超时时间
const string kTimeoutSec = RTP_PROXY_FIELD"timeoutSec";

onceToken token([](){
288 289
    mINI::Instance()[kDumpDir] = "";
    mINI::Instance()[kTimeoutSec] = 15;
290 291 292 293
},nullptr);
} //namespace RtpProxy


xiongziliang committed
294
namespace Client {
295 296 297 298 299 300 301 302 303
const string kNetAdapter = "net_adapter";
const string kRtpType = "rtp_type";
const string kRtspUser = "rtsp_user" ;
const string kRtspPwd = "rtsp_pwd";
const string kRtspPwdIsMD5 = "rtsp_pwd_md5";
const string kTimeoutMS = "protocol_timeout_ms";
const string kMediaTimeoutMS = "media_timeout_ms";
const string kBeatIntervalMS = "beat_interval_ms";
const string kMaxAnalysisMS = "max_analysis_ms";
304 305
const string kBenchmarkMode = "benchmark_mode";

xiongziliang committed
306 307
}

xiongziliang committed
308
}  // namespace mediakit
xzl committed
309

310 311 312
extern "C" {
void Assert_Throw(int failed, const char *exp, const char *func, const char *file, int line) {
    if (failed) {
313
        _StrPrinter printer;
314 315
        printer << "Assertion failed: (" << exp << "), function " << func << ", file " << file << ", line " << line
                << ".";
316 317 318
        throw std::runtime_error(printer);
    }
}
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
}

#ifdef ENABLE_MEM_DEBUG

static atomic<uint64_t> mem_usage(0);

uint64_t getTotalMemUsage() {
    return mem_usage.load();
}

extern "C" {

#include <stdio.h>
#define MAGIC_BYTES 0xFEFDFCFB
#define MAGIC_BYTES_SIZE 4
#define MEM_PREFIX_SIZE 8

extern void *__real_malloc(size_t);
extern void __real_free(void *);
extern void *__real_realloc(void *ptr, size_t c);

void *__wrap_malloc(size_t c) {
    c += MEM_PREFIX_SIZE;
    char *ret = (char *) __real_malloc(c);
    if (ret) {
        mem_usage += c;
        *((uint32_t *) (ret)) = MAGIC_BYTES;
        *((uint32_t *) (ret + MAGIC_BYTES_SIZE)) = c;
        return ret + MEM_PREFIX_SIZE;
    }
    return nullptr;
}

void __wrap_free(void *ptr) {
    if (!ptr) {
        return;
    }
    ptr = (char *) ptr - MEM_PREFIX_SIZE;
    uint32_t magic = *((uint32_t *) (ptr));
    if (magic != MAGIC_BYTES) {
        throw std::invalid_argument("attempt to free invalid memory");
    }
    mem_usage -= *((uint32_t *) ((char *) ptr + MAGIC_BYTES_SIZE));
    __real_free(ptr);
}

void *__wrap_calloc(size_t __nmemb, size_t __size) {
    auto size = __nmemb * __size;
    auto ret = malloc(size);
    if (ret) {
        memset(ret, 0, size);
    }
    return ret;
}

void *__wrap_realloc(void *ptr, size_t c){
    if (!ptr) {
        return malloc(c);
    }
    c += MEM_PREFIX_SIZE;
    ptr = (char *) ptr - MEM_PREFIX_SIZE;

    uint32_t magic = *((uint32_t *) (ptr));
    if (magic != MAGIC_BYTES) {
        throw std::invalid_argument("attempt to realloc invalid memory");
    }
    auto old_size = *((uint32_t *) ((char *) ptr + MAGIC_BYTES_SIZE));
    char *ret = (char *) __real_realloc(ptr, c);
    if (ret) {
        mem_usage += c - old_size;
        *((uint32_t *) (ret)) = MAGIC_BYTES;
        *((uint32_t *) (ret + MAGIC_BYTES_SIZE)) = c;
        return ret + MEM_PREFIX_SIZE;
    }
    free(ptr);
    mem_usage -= old_size;
    return nullptr;
}

}

void *operator new(std::size_t size) {
    auto ret = malloc(size);
    if (ret) {
        return ret;
    }
    throw std::bad_alloc();
}

void operator delete(void *ptr) {
    free(ptr);
}

void *operator new[](std::size_t size) {
    auto ret = malloc(size);
    if (ret) {
        return ret;
    }
    throw std::bad_alloc();
}

void operator delete[](void *ptr) {
    free(ptr);
}
#endif