Merge branch 'master' of https://gitee.com/xia-chu/ZLMediaKit into open_src

This commit is contained in:
xiongziliang 2020-12-13 09:56:26 +08:00
commit 8b134d5b2d
2 changed files with 67 additions and 52 deletions

View File

@ -12,7 +12,6 @@
#include <math.h> #include <math.h>
#include <signal.h> #include <signal.h>
#include <functional> #include <functional>
#include <sstream>
#include <unordered_map> #include <unordered_map>
#include "jsoncpp/json.h" #include "jsoncpp/json.h"
#include "Util/util.h" #include "Util/util.h"
@ -98,25 +97,58 @@ public:
#define API_ARGS1 SockInfo &sender,HttpSession::KeyValue &headerIn, HttpSession::KeyValue &headerOut, ApiArgsType &allArgs, Json::Value &val #define API_ARGS1 SockInfo &sender,HttpSession::KeyValue &headerIn, HttpSession::KeyValue &headerOut, ApiArgsType &allArgs, Json::Value &val
#define API_ARGS2 API_ARGS1, const HttpSession::HttpResponseInvoker &invoker #define API_ARGS2 API_ARGS1, const HttpSession::HttpResponseInvoker &invoker
#define API_ARGS_VALUE1 sender,headerIn,headerOut,allArgs,val #define API_ARGS_VALUE1 sender,headerIn,headerOut,allArgs,val
#define API_ARGS_VALUE2 API_ARGS_VALUE1, invoker
typedef map<string, variant, StrCaseCompare> ApiArgsType; typedef map<string, variant, StrCaseCompare> ApiArgsType;
typedef function<void(const Parser &parser, const HttpSession::HttpResponseInvoker &invoker, SockInfo &sender)> HttpApi;
//http api列表 //http api列表
static map<string, std::function<void(API_ARGS2)> > s_map_api; static map<string, HttpApi> s_map_api;
template<typename FUNC> static void responseApi(const Json::Value &res, const HttpSession::HttpResponseInvoker &invoker){
static void api_regist1(const string &api_path, FUNC &&func) { GET_CONFIG(string, charSet, Http::kCharSet);
s_map_api.emplace(api_path, [func](API_ARGS2) { HttpSession::KeyValue headerOut;
func(API_ARGS_VALUE1); headerOut["Content-Type"] = string("application/json; charset=") + charSet;
invoker("200 OK", headerOut, res.toStyledString());
};
static void responseApi(int code, const string &msg, const HttpSession::HttpResponseInvoker &invoker){
Json::Value res;
res["code"] = code;
res["msg"] = msg;
responseApi(res, invoker);
}
static ApiArgsType getAllArgs(const Parser &parser);
static HttpApi toApi(const function<void(API_ARGS2)> &cb) {
return [cb](const Parser &parser, const HttpSession::HttpResponseInvoker &invoker, SockInfo &sender) {
GET_CONFIG(string, charSet, Http::kCharSet);
HttpSession::KeyValue headerOut;
headerOut["Content-Type"] = string("application/json; charset=") + charSet;
Json::Value val;
val["code"] = API::Success;
auto args = getAllArgs(parser);
cb(sender, parser.getHeader(), headerOut, args, val, invoker);
};
}
static HttpApi toApi(const function<void(API_ARGS1)> &cb) {
return toApi([cb](API_ARGS2) {
cb(API_ARGS_VALUE1);
invoker("200 OK", headerOut, val.toStyledString()); invoker("200 OK", headerOut, val.toStyledString());
}); });
} }
template<typename FUNC> template<typename FUNC>
static void api_regist2(const string &api_path, FUNC &&func) { static void api_regist(const string &api_path, FUNC &&func) {
s_map_api.emplace(api_path, std::forward<FUNC>(func)); s_map_api.emplace(api_path, toApi(std::move(func)));
} }
#define api_regist1 api_regist
#define api_regist2 api_regist
//获取HTTP请求中url参数、content参数 //获取HTTP请求中url参数、content参数
static ApiArgsType getAllArgs(const Parser &parser) { static ApiArgsType getAllArgs(const Parser &parser) {
ApiArgsType allArgs; ApiArgsType allArgs;
@ -157,22 +189,11 @@ static inline void addHttpListener(){
} }
//该api已被消费 //该api已被消费
consumed = true; consumed = true;
//执行API
Json::Value val;
val["code"] = API::Success;
HttpSession::KeyValue headerOut;
auto allArgs = getAllArgs(parser);
HttpSession::KeyValue &headerIn = parser.getHeader();
GET_CONFIG(string,charSet,Http::kCharSet);
headerOut["Content-Type"] = StrPrinter << "application/json; charset=" << charSet;
if(api_debug){ if(api_debug){
auto newInvoker = [invoker,parser,allArgs](const string &codeOut, auto newInvoker = [invoker, parser](const string &codeOut,
const HttpSession::KeyValue &headerOut, const HttpSession::KeyValue &headerOut,
const HttpBody::Ptr &body) { const HttpBody::Ptr &body) {
stringstream ss;
for(auto &pr : allArgs ){
ss << pr.first << " : " << pr.second << "\r\n";
}
//body默认为空 //body默认为空
int64_t size = 0; int64_t size = 0;
@ -185,14 +206,12 @@ static inline void addHttpListener(){
string contentOut = body->readData(size)->toString(); string contentOut = body->readData(size)->toString();
DebugL << "\r\n# request:\r\n" << parser.Method() << " " << parser.FullUrl() << "\r\n" DebugL << "\r\n# request:\r\n" << parser.Method() << " " << parser.FullUrl() << "\r\n"
<< "# content:\r\n" << parser.Content() << "\r\n" << "# content:\r\n" << parser.Content() << "\r\n"
<< "# args:\r\n" << ss.str()
<< "# response:\r\n" << "# response:\r\n"
<< contentOut << "\r\n"; << contentOut << "\r\n";
invoker(codeOut, headerOut, contentOut); invoker(codeOut, headerOut, contentOut);
} else { } else {
DebugL << "\r\n# request:\r\n" << parser.Method() << " " << parser.FullUrl() << "\r\n" DebugL << "\r\n# request:\r\n" << parser.Method() << " " << parser.FullUrl() << "\r\n"
<< "# content:\r\n" << parser.Content() << "\r\n" << "# content:\r\n" << parser.Content() << "\r\n"
<< "# args:\r\n" << ss.str()
<< "# response size:" << "# response size:"
<< size << "\r\n"; << size << "\r\n";
invoker(codeOut, headerOut, body); invoker(codeOut, headerOut, body);
@ -202,24 +221,17 @@ static inline void addHttpListener(){
} }
try { try {
it->second(sender,headerIn, headerOut, allArgs, val, invoker); it->second(parser, invoker, sender);
} catch (ApiRetException &ex) { } catch (ApiRetException &ex) {
val["code"] = ex.code(); responseApi(ex.code(), ex.what(), invoker);
val["msg"] = ex.what();
invoker("200 OK", headerOut, val.toStyledString());
} }
#ifdef ENABLE_MYSQL #ifdef ENABLE_MYSQL
catch(SqlException &ex){ catch(SqlException &ex){
val["code"] = API::SqlFailed; responseApi(API::SqlFailed, StrPrinter << "操作数据库失败:" << ex.what() << ":" << ex.getSql(), invoker);
val["msg"] = StrPrinter << "操作数据库失败:" << ex.what() << ":" << ex.getSql();
WarnL << ex.what() << ":" << ex.getSql();
invoker("200 OK", headerOut, val.toStyledString());
} }
#endif// ENABLE_MYSQL #endif// ENABLE_MYSQL
catch (std::exception &ex) { catch (std::exception &ex) {
val["code"] = API::Exception; responseApi(API::Exception, ex.what(), invoker);
val["msg"] = ex.what();
invoker("200 OK", headerOut, val.toStyledString());
} }
}); });
} }

View File

@ -101,16 +101,18 @@ bool RtpReceiver::handleOneRtp(int track_index, TrackType type, int samplerate,
//ssrc匹配正确不匹配计数清零 //ssrc匹配正确不匹配计数清零
_ssrc_err_count[track_index] = 0; _ssrc_err_count[track_index] = 0;
//获取rtp中媒体数据偏移量 //rtp 12个固定字节头
rtp.offset = 12 + 4; rtp.offset = 12;
//rtp有csrc
rtp.offset += 4 * csrc; rtp.offset += 4 * csrc;
if (ext && rtp_raw_len >= rtp.offset) { if (ext) {
/* calculate the header extension length (stored as number of 32-bit words) */ //rtp有ext
ext = (AV_RB16(rtp_raw_ptr + rtp.offset - 2) + 1) << 2; uint16_t reserved = AV_RB16(rtp_raw_ptr + rtp.offset);
rtp.offset += ext; uint16_t extlen = AV_RB16(rtp_raw_ptr + rtp.offset + 2) << 2;
rtp.offset += extlen + 4;
} }
if (rtp_raw_len + 4 <= rtp.offset) { if (rtp_raw_len <= rtp.offset) {
WarnL << "无有效负载的rtp包:" << rtp_raw_len << " <= " << (int) rtp.offset; WarnL << "无有效负载的rtp包:" << rtp_raw_len << " <= " << (int) rtp.offset;
return false; return false;
} }
@ -128,9 +130,10 @@ bool RtpReceiver::handleOneRtp(int track_index, TrackType type, int samplerate,
payload_ptr[1] = rtp.interleaved; payload_ptr[1] = rtp.interleaved;
payload_ptr[2] = rtp_raw_len >> 8; payload_ptr[2] = rtp_raw_len >> 8;
payload_ptr[3] = (rtp_raw_len & 0x00FF); payload_ptr[3] = (rtp_raw_len & 0x00FF);
//添加rtp over tcp前4个字节的偏移量
rtp.offset += 4;
//拷贝rtp负载 //拷贝rtp负载
memcpy(payload_ptr + 4, rtp_raw_ptr, rtp_raw_len); memcpy(payload_ptr + 4, rtp_raw_ptr, rtp_raw_len);
//排序rtp //排序rtp
auto seq = rtp_ptr->sequence; auto seq = rtp_ptr->sequence;
_rtp_sortor[track_index].sortPacket(seq, std::move(rtp_ptr)); _rtp_sortor[track_index].sortPacket(seq, std::move(rtp_ptr));