mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-25 11:12:21 +08:00
Merge branch 'master' of github.com:ZLMediaKit/ZLMediaKit into transcode2
# Conflicts: # CMakeLists.txt # conf/config.ini # src/Common/MediaSink.cpp # src/Common/MediaSink.h # src/Common/MediaSource.cpp # src/Common/MultiMediaSourceMuxer.h # src/Common/config.cpp # src/Common/config.h # src/Extension/AAC.cpp # src/Extension/AAC.h # src/Rtsp/RtpCodec.h # src/Rtsp/RtspMuxer.cpp # src/Rtsp/RtspMuxer.h # webrtc/Nack.cpp # webrtc/WebRtcTransport.cpp
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
@@ -33,12 +33,11 @@ static TcpServer::Ptr shell_server;
|
||||
|
||||
#ifdef ENABLE_RTPPROXY
|
||||
#include "Rtp/RtpServer.h"
|
||||
static std::shared_ptr<RtpServer> rtpServer;
|
||||
static RtpServer::Ptr rtpServer;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_WEBRTC
|
||||
#include "../webrtc/WebRtcSession.h"
|
||||
#include "../webrtc/WebRtcTransport.h"
|
||||
static UdpServer::Ptr rtcServer_udp;
|
||||
static TcpServer::Ptr rtcServer_tcp;
|
||||
#endif
|
||||
@@ -84,7 +83,7 @@ API_EXPORT void API_CALL mk_stop_all_server(){
|
||||
stopAllTcpServer();
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_env_init1(int thread_num,
|
||||
API_EXPORT void API_CALL mk_env_init2(int thread_num,
|
||||
int log_level,
|
||||
int log_mask,
|
||||
const char *log_file_path,
|
||||
@@ -159,7 +158,7 @@ API_EXPORT void API_CALL mk_set_option(const char *key, const char *val) {
|
||||
}
|
||||
mINI::Instance()[key] = val;
|
||||
//广播配置文件热加载
|
||||
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastReloadConfig);
|
||||
NOTICE_EMIT(BroadcastReloadConfigArgs, Broadcast::kBroadcastReloadConfig);
|
||||
}
|
||||
|
||||
API_EXPORT const char * API_CALL mk_get_option(const char *key)
|
||||
@@ -280,7 +279,6 @@ API_EXPORT uint16_t API_CALL mk_rtc_server_start(uint16_t port) {
|
||||
class WebRtcArgsUrl : public mediakit::WebRtcArgs {
|
||||
public:
|
||||
WebRtcArgsUrl(std::string url) { _url = std::move(url); }
|
||||
~WebRtcArgsUrl() = default;
|
||||
|
||||
toolkit::variant operator[](const std::string &key) const override {
|
||||
if (key == "url") {
|
||||
@@ -305,10 +303,11 @@ API_EXPORT void API_CALL mk_webrtc_get_answer_sdp2(void *user_data, on_user_data
|
||||
auto session = std::make_shared<HttpSession>(Socket::createSocket());
|
||||
std::string offer_str = offer;
|
||||
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
|
||||
WebRtcPluginManager::Instance().getAnswerSdp(*session, type, WebRtcArgsUrl(url),
|
||||
[offer_str, session, ptr, cb](const WebRtcInterface &exchanger) mutable {
|
||||
auto args = std::make_shared<WebRtcArgsUrl>(url);
|
||||
WebRtcPluginManager::Instance().negotiateSdp(*session, type, *args, [offer_str, session, ptr, cb](const WebRtcInterface &exchanger) mutable {
|
||||
auto &handler = const_cast<WebRtcInterface &>(exchanger);
|
||||
try {
|
||||
auto sdp_answer = exchangeSdp(exchanger, offer_str);
|
||||
auto sdp_answer = handler.getAnswerSdp(offer_str);
|
||||
cb(ptr.get(), sdp_answer.data(), nullptr);
|
||||
} catch (std::exception &ex) {
|
||||
cb(ptr.get(), nullptr, ex.what());
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
@@ -15,6 +15,10 @@
|
||||
#include "Rtsp/RtspSession.h"
|
||||
#include "Record/MP4Recorder.h"
|
||||
|
||||
#ifdef ENABLE_WEBRTC
|
||||
#include "webrtc/WebRtcTransport.h"
|
||||
#endif
|
||||
|
||||
using namespace toolkit;
|
||||
using namespace mediakit;
|
||||
|
||||
@@ -38,7 +42,13 @@ API_EXPORT void API_CALL mk_events_listen(const mk_events *events){
|
||||
|
||||
NoticeCenter::Instance().addListener(&s_tag,Broadcast::kBroadcastRecordMP4,[](BroadcastRecordMP4Args){
|
||||
if(s_events.on_mk_record_mp4){
|
||||
s_events.on_mk_record_mp4((mk_mp4_info)&info);
|
||||
s_events.on_mk_record_mp4((mk_record_info)&info);
|
||||
}
|
||||
});
|
||||
|
||||
NoticeCenter::Instance().addListener(&s_tag, Broadcast::kBroadcastRecordTs, [](BroadcastRecordTsArgs) {
|
||||
if (s_events.on_mk_record_ts) {
|
||||
s_events.on_mk_record_ts((mk_record_info)&info);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -167,6 +177,43 @@ API_EXPORT void API_CALL mk_events_listen(const mk_events *events){
|
||||
sender.getMediaTuple().stream.c_str(), ssrc.c_str(), ex.getErrCode(), ex.what());
|
||||
}
|
||||
});
|
||||
#ifdef ENABLE_WEBRTC
|
||||
NoticeCenter::Instance().addListener(&s_tag, Broadcast::kBroadcastRtcSctpConnecting,[](BroadcastRtcSctpConnectArgs){
|
||||
if (s_events.on_mk_rtc_sctp_connecting) {
|
||||
s_events.on_mk_rtc_sctp_connecting((mk_rtc_transport)&sender);
|
||||
}
|
||||
});
|
||||
|
||||
NoticeCenter::Instance().addListener(&s_tag, Broadcast::kBroadcastRtcSctpConnected,[](BroadcastRtcSctpConnectArgs){
|
||||
if (s_events.on_mk_rtc_sctp_connected) {
|
||||
s_events.on_mk_rtc_sctp_connected((mk_rtc_transport)&sender);
|
||||
}
|
||||
});
|
||||
|
||||
NoticeCenter::Instance().addListener(&s_tag, Broadcast::kBroadcastRtcSctpFailed,[](BroadcastRtcSctpConnectArgs){
|
||||
if (s_events.on_mk_rtc_sctp_failed) {
|
||||
s_events.on_mk_rtc_sctp_failed((mk_rtc_transport)&sender);
|
||||
}
|
||||
});
|
||||
|
||||
NoticeCenter::Instance().addListener(&s_tag, Broadcast::kBroadcastRtcSctpClosed,[](BroadcastRtcSctpConnectArgs){
|
||||
if (s_events.on_mk_rtc_sctp_closed) {
|
||||
s_events.on_mk_rtc_sctp_closed((mk_rtc_transport)&sender);
|
||||
}
|
||||
});
|
||||
|
||||
NoticeCenter::Instance().addListener(&s_tag, Broadcast::kBroadcastRtcSctpSend,[](BroadcastRtcSctpSendArgs){
|
||||
if (s_events.on_mk_rtc_sctp_send) {
|
||||
s_events.on_mk_rtc_sctp_send((mk_rtc_transport)&sender, data, len);
|
||||
}
|
||||
});
|
||||
|
||||
NoticeCenter::Instance().addListener(&s_tag, Broadcast::kBroadcastRtcSctpReceived,[](BroadcastRtcSctpReceivedArgs){
|
||||
if (s_events.on_mk_rtc_sctp_received) {
|
||||
s_events.on_mk_rtc_sctp_received((mk_rtc_transport)&sender, streamId, ppid, msg, len);
|
||||
}
|
||||
});
|
||||
#endif
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
@@ -18,65 +18,69 @@
|
||||
#include "Http/HttpClient.h"
|
||||
#include "Rtsp/RtspSession.h"
|
||||
|
||||
#ifdef ENABLE_WEBRTC
|
||||
#include "webrtc/WebRtcTransport.h"
|
||||
#endif
|
||||
|
||||
using namespace toolkit;
|
||||
using namespace mediakit;
|
||||
|
||||
///////////////////////////////////////////RecordInfo/////////////////////////////////////////////
|
||||
API_EXPORT uint64_t API_CALL mk_mp4_info_get_start_time(const mk_mp4_info ctx){
|
||||
API_EXPORT uint64_t API_CALL mk_record_info_get_start_time(const mk_record_info ctx) {
|
||||
assert(ctx);
|
||||
RecordInfo *info = (RecordInfo *)ctx;
|
||||
return info->start_time;
|
||||
}
|
||||
|
||||
API_EXPORT float API_CALL mk_mp4_info_get_time_len(const mk_mp4_info ctx){
|
||||
API_EXPORT float API_CALL mk_record_info_get_time_len(const mk_record_info ctx) {
|
||||
assert(ctx);
|
||||
RecordInfo *info = (RecordInfo *)ctx;
|
||||
return info->time_len;
|
||||
}
|
||||
|
||||
API_EXPORT size_t API_CALL mk_mp4_info_get_file_size(const mk_mp4_info ctx){
|
||||
API_EXPORT size_t API_CALL mk_record_info_get_file_size(const mk_record_info ctx) {
|
||||
assert(ctx);
|
||||
RecordInfo *info = (RecordInfo *)ctx;
|
||||
return info->file_size;
|
||||
}
|
||||
|
||||
API_EXPORT const char* API_CALL mk_mp4_info_get_file_path(const mk_mp4_info ctx){
|
||||
API_EXPORT const char *API_CALL mk_record_info_get_file_path(const mk_record_info ctx) {
|
||||
assert(ctx);
|
||||
RecordInfo *info = (RecordInfo *)ctx;
|
||||
return info->file_path.c_str();
|
||||
}
|
||||
|
||||
API_EXPORT const char* API_CALL mk_mp4_info_get_file_name(const mk_mp4_info ctx){
|
||||
API_EXPORT const char *API_CALL mk_record_info_get_file_name(const mk_record_info ctx) {
|
||||
assert(ctx);
|
||||
RecordInfo *info = (RecordInfo *)ctx;
|
||||
return info->file_name.c_str();
|
||||
}
|
||||
|
||||
API_EXPORT const char* API_CALL mk_mp4_info_get_folder(const mk_mp4_info ctx){
|
||||
API_EXPORT const char *API_CALL mk_record_info_get_folder(const mk_record_info ctx) {
|
||||
assert(ctx);
|
||||
RecordInfo *info = (RecordInfo *)ctx;
|
||||
return info->folder.c_str();
|
||||
}
|
||||
|
||||
API_EXPORT const char* API_CALL mk_mp4_info_get_url(const mk_mp4_info ctx){
|
||||
API_EXPORT const char *API_CALL mk_record_info_get_url(const mk_record_info ctx) {
|
||||
assert(ctx);
|
||||
RecordInfo *info = (RecordInfo *)ctx;
|
||||
return info->url.c_str();
|
||||
}
|
||||
|
||||
API_EXPORT const char* API_CALL mk_mp4_info_get_vhost(const mk_mp4_info ctx){
|
||||
API_EXPORT const char *API_CALL mk_record_info_get_vhost(const mk_record_info ctx) {
|
||||
assert(ctx);
|
||||
RecordInfo *info = (RecordInfo *)ctx;
|
||||
return info->vhost.c_str();
|
||||
}
|
||||
|
||||
API_EXPORT const char* API_CALL mk_mp4_info_get_app(const mk_mp4_info ctx){
|
||||
API_EXPORT const char *API_CALL mk_record_info_get_app(const mk_record_info ctx) {
|
||||
assert(ctx);
|
||||
RecordInfo *info = (RecordInfo *)ctx;
|
||||
return info->app.c_str();
|
||||
}
|
||||
|
||||
API_EXPORT const char* API_CALL mk_mp4_info_get_stream(const mk_mp4_info ctx){
|
||||
API_EXPORT const char *API_CALL mk_record_info_get_stream(const mk_record_info ctx) {
|
||||
assert(ctx);
|
||||
RecordInfo *info = (RecordInfo *)ctx;
|
||||
return info->stream.c_str();
|
||||
@@ -121,12 +125,19 @@ API_EXPORT const char* API_CALL mk_parser_get_content(const mk_parser ctx, size_
|
||||
}
|
||||
return parser->content().c_str();
|
||||
}
|
||||
API_EXPORT void API_CALL mk_parser_headers_for_each(const mk_parser ctx, on_mk_parser_header_cb cb, void *user_data){
|
||||
assert(ctx && cb);
|
||||
Parser *parser = (Parser *)ctx;
|
||||
for (auto it = parser->getHeader().begin(); it != parser->getHeader().end(); ++it) {
|
||||
cb(user_data, it->first.c_str(), it->second.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////MediaInfo/////////////////////////////////////////////
|
||||
API_EXPORT const char* API_CALL mk_media_info_get_params(const mk_media_info ctx){
|
||||
assert(ctx);
|
||||
MediaInfo *info = (MediaInfo *)ctx;
|
||||
return info->param_strs.c_str();
|
||||
return info->params.c_str();
|
||||
}
|
||||
|
||||
API_EXPORT const char* API_CALL mk_media_info_get_schema(const mk_media_info ctx){
|
||||
@@ -214,6 +225,66 @@ API_EXPORT mk_track API_CALL mk_media_source_get_track(const mk_media_source ctx
|
||||
return (mk_track) new Track::Ptr(std::move(tracks[index]));
|
||||
}
|
||||
|
||||
API_EXPORT float API_CALL mk_media_source_get_track_loss(const mk_media_source ctx, const mk_track track) {
|
||||
assert(ctx);
|
||||
MediaSource *src = (MediaSource *)ctx;
|
||||
// rtp推流只有一个统计器,但是可能有多个track,如果短时间多次获取间隔丢包率,第二次会获取为-1
|
||||
return src->getLossRate((*((Track::Ptr *)track))->getTrackType());
|
||||
}
|
||||
|
||||
API_EXPORT int API_CALL mk_media_source_broadcast_msg(const mk_media_source ctx, const char *msg, size_t len) {
|
||||
assert(ctx && msg && len);
|
||||
MediaSource *src = (MediaSource *)ctx;
|
||||
|
||||
Any any;
|
||||
Buffer::Ptr buffer = std::make_shared<BufferLikeString>(std::string(msg, len));
|
||||
any.set(std::move(buffer));
|
||||
return src->broadcastMessage(any);
|
||||
}
|
||||
|
||||
API_EXPORT const char* API_CALL mk_media_source_get_origin_url(const mk_media_source ctx) {
|
||||
assert(ctx);
|
||||
MediaSource *src = (MediaSource *)ctx;
|
||||
return _strdup(src->getOriginUrl().c_str());
|
||||
}
|
||||
|
||||
API_EXPORT int API_CALL mk_media_source_get_origin_type(const mk_media_source ctx) {
|
||||
assert(ctx);
|
||||
MediaSource *src = (MediaSource *)ctx;
|
||||
return static_cast<int>(src->getOriginType());
|
||||
}
|
||||
|
||||
API_EXPORT const char* API_CALL mk_media_source_get_origin_type_str(const mk_media_source ctx) {
|
||||
assert(ctx);
|
||||
MediaSource *src = (MediaSource *)ctx;
|
||||
return _strdup(getOriginTypeString(src->getOriginType()).c_str());
|
||||
}
|
||||
|
||||
API_EXPORT uint64_t API_CALL mk_media_source_get_create_stamp(const mk_media_source ctx) {
|
||||
assert(ctx);
|
||||
MediaSource *src = (MediaSource *)ctx;
|
||||
return src->getCreateStamp();
|
||||
}
|
||||
|
||||
API_EXPORT int API_CALL mk_media_source_is_recording(const mk_media_source ctx,int type) {
|
||||
assert(ctx);
|
||||
MediaSource *src = (MediaSource *)ctx;
|
||||
return src->isRecording((Recorder::type)type);
|
||||
}
|
||||
|
||||
API_EXPORT int API_CALL mk_media_source_get_bytes_speed(const mk_media_source ctx) {
|
||||
assert(ctx);
|
||||
MediaSource *src = (MediaSource *)ctx;
|
||||
return src->getBytesSpeed();
|
||||
}
|
||||
|
||||
API_EXPORT uint64_t API_CALL mk_media_source_get_alive_second(const mk_media_source ctx) {
|
||||
assert(ctx);
|
||||
MediaSource *src = (MediaSource *)ctx;
|
||||
return src->getAliveSecond();
|
||||
}
|
||||
|
||||
|
||||
API_EXPORT int API_CALL mk_media_source_close(const mk_media_source ctx,int force){
|
||||
assert(ctx);
|
||||
MediaSource *src = (MediaSource *)ctx;
|
||||
@@ -264,11 +335,11 @@ API_EXPORT void API_CALL mk_media_source_find(const char *schema,
|
||||
cb(user_data, (mk_media_source)src.get());
|
||||
}
|
||||
|
||||
API_EXPORT const mk_media_source API_CALL mk_media_source_find2(const char *schema,
|
||||
const char *vhost,
|
||||
const char *app,
|
||||
const char *stream,
|
||||
int from_mp4) {
|
||||
API_EXPORT mk_media_source API_CALL mk_media_source_find2(const char *schema,
|
||||
const char *vhost,
|
||||
const char *app,
|
||||
const char *stream,
|
||||
int from_mp4) {
|
||||
assert(schema && vhost && app && stream);
|
||||
auto src = MediaSource::find(schema, vhost, app, stream, from_mp4);
|
||||
return (mk_media_source)src.get();
|
||||
@@ -451,6 +522,13 @@ API_EXPORT void API_CALL mk_publish_auth_invoker_do(const mk_publish_auth_invoke
|
||||
(*invoker)(err_msg ? err_msg : "", option);
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_publish_auth_invoker_do2(const mk_publish_auth_invoker ctx, const char *err_msg, mk_ini ini) {
|
||||
assert(ctx);
|
||||
Broadcast::PublishAuthInvoker *invoker = (Broadcast::PublishAuthInvoker *)ctx;
|
||||
ProtocolOption option(ini ? *((mINI *)ini) : mINI{} );
|
||||
(*invoker)(err_msg ? err_msg : "", option);
|
||||
}
|
||||
|
||||
API_EXPORT mk_publish_auth_invoker API_CALL mk_publish_auth_invoker_clone(const mk_publish_auth_invoker ctx){
|
||||
assert(ctx);
|
||||
Broadcast::PublishAuthInvoker *invoker = (Broadcast::PublishAuthInvoker *)ctx;
|
||||
@@ -480,4 +558,22 @@ API_EXPORT void API_CALL mk_auth_invoker_clone_release(const mk_auth_invoker ctx
|
||||
assert(ctx);
|
||||
Broadcast::AuthInvoker *invoker = (Broadcast::AuthInvoker *)ctx;
|
||||
delete invoker;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////WebRtcTransport/////////////////////////////////////////////
|
||||
API_EXPORT void API_CALL mk_rtc_send_datachannel(const mk_rtc_transport ctx, uint16_t streamId, uint32_t ppid, const char *msg, size_t len) {
|
||||
#ifdef ENABLE_WEBRTC
|
||||
assert(ctx && msg);
|
||||
WebRtcTransport *transport = (WebRtcTransport *)ctx;
|
||||
std::string msg_str(msg, len);
|
||||
std::weak_ptr<WebRtcTransport> weak_trans = transport->shared_from_this();
|
||||
transport->getPoller()->async([streamId, ppid, msg_str, weak_trans]() {
|
||||
// 切换线程后再操作
|
||||
if (auto trans = weak_trans.lock()) {
|
||||
trans->sendDatachannel(streamId, ppid, msg_str.c_str(), msg_str.size());
|
||||
}
|
||||
});
|
||||
#else
|
||||
WarnL << "未启用webrtc功能, 编译时请开启ENABLE_WEBRTC";
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,115 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
|
||||
#include "mk_frame.h"
|
||||
#include "mk_track.h"
|
||||
#include "Extension/Frame.h"
|
||||
#include "Extension/H264.h"
|
||||
#include "Extension/H265.h"
|
||||
#include "Extension/AAC.h"
|
||||
#include "Record/MPEG.h"
|
||||
#include "Extension/Factory.h"
|
||||
|
||||
using namespace mediakit;
|
||||
|
||||
extern "C" {
|
||||
#define XX(name, type, value, str, mpeg_id) API_EXPORT const int MK##name = value;
|
||||
#define XX(name, type, value, str, mpeg_id, mp4_id) API_EXPORT const int MK##name = value;
|
||||
CODEC_MAP(XX)
|
||||
#undef XX
|
||||
}
|
||||
|
||||
class FrameFromPtrForC : public FrameFromPtr {
|
||||
namespace {
|
||||
class BufferFromPtr : public toolkit::Buffer {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<FrameFromPtrForC>;
|
||||
|
||||
template<typename ...ARGS>
|
||||
FrameFromPtrForC(bool cache_able, uint32_t flags, on_mk_frame_data_release cb, std::shared_ptr<void> user_data, ARGS &&...args) : FrameFromPtr(
|
||||
std::forward<ARGS>(args)...) {
|
||||
_flags = flags;
|
||||
BufferFromPtr(char *ptr, size_t size, on_mk_frame_data_release cb, std::shared_ptr<void> user_data) {
|
||||
_ptr = ptr;
|
||||
_size = size;
|
||||
_cb = cb;
|
||||
_user_data = std::move(user_data);
|
||||
_cache_able = cache_able;
|
||||
}
|
||||
|
||||
~FrameFromPtrForC() override {
|
||||
if (_cb) {
|
||||
_cb(_user_data.get(), _ptr);
|
||||
}
|
||||
~BufferFromPtr() override {
|
||||
_cb(_user_data.get(), _ptr);
|
||||
}
|
||||
|
||||
bool cacheAble() const override {
|
||||
return _cache_able;
|
||||
}
|
||||
|
||||
bool keyFrame() const override {
|
||||
return _flags & MK_FRAME_FLAG_IS_KEY;
|
||||
}
|
||||
|
||||
bool configFrame() const override {
|
||||
return _flags & MK_FRAME_FLAG_IS_CONFIG;
|
||||
}
|
||||
|
||||
//默认返回false
|
||||
bool dropAble() const override {
|
||||
return _flags & MK_FRAME_FLAG_DROP_ABLE;
|
||||
}
|
||||
|
||||
//默认返回true
|
||||
bool decodeAble() const override {
|
||||
return !(_flags & MK_FRAME_FLAG_NOT_DECODE_ABLE);
|
||||
}
|
||||
char *data() const override { return _ptr; }
|
||||
size_t size() const override { return _size; }
|
||||
|
||||
private:
|
||||
uint32_t _flags;
|
||||
char *_ptr;
|
||||
size_t _size;
|
||||
on_mk_frame_data_release _cb;
|
||||
std::shared_ptr<void> _user_data;
|
||||
bool _cache_able;
|
||||
};
|
||||
}; // namespace
|
||||
|
||||
static mk_frame mk_frame_create_complex(int codec_id, uint64_t dts, uint64_t pts, uint32_t frame_flags, size_t prefix_size,
|
||||
char *data, size_t size, on_mk_frame_data_release cb, std::shared_ptr<void> user_data) {
|
||||
switch (codec_id) {
|
||||
case CodecH264:
|
||||
return (mk_frame)new Frame::Ptr(new H264FrameHelper<FrameFromPtrForC>(
|
||||
cb, frame_flags, cb, std::move(user_data), (CodecId)codec_id, data, size, dts, pts, prefix_size));
|
||||
case CodecH265:
|
||||
return (mk_frame)new Frame::Ptr(new H265FrameHelper<FrameFromPtrForC>(
|
||||
cb, frame_flags, cb, std::move(user_data), (CodecId)codec_id, data, size, dts, pts, prefix_size));
|
||||
default:
|
||||
return (mk_frame)new Frame::Ptr(new FrameFromPtrForC(
|
||||
cb, frame_flags, cb, std::move(user_data), (CodecId)codec_id, data, size, dts, pts, prefix_size));
|
||||
static mk_frame mk_frame_create_complex(int codec_id, uint64_t dts, uint64_t pts, const char *data, size_t size,
|
||||
on_mk_frame_data_release cb, std::shared_ptr<void> user_data) {
|
||||
if (!cb) {
|
||||
// no cacheable
|
||||
return (mk_frame) new Frame::Ptr(Factory::getFrameFromPtr((CodecId)codec_id, data, size, dts, pts));
|
||||
}
|
||||
// cacheable
|
||||
auto buffer = std::make_shared<BufferFromPtr>((char *)data, size, cb, std::move(user_data));
|
||||
return (mk_frame) new Frame::Ptr(Factory::getFrameFromBuffer((CodecId)codec_id, std::move(buffer), dts, pts));
|
||||
}
|
||||
|
||||
API_EXPORT mk_frame API_CALL mk_frame_create(int codec_id, uint64_t dts, uint64_t pts, const char *data, size_t size,
|
||||
on_mk_frame_data_release cb, void *user_data) {
|
||||
on_mk_frame_data_release cb, void *user_data) {
|
||||
return mk_frame_create2(codec_id, dts, pts, data, size, cb, user_data, nullptr);
|
||||
}
|
||||
|
||||
API_EXPORT mk_frame API_CALL mk_frame_create2(int codec_id, uint64_t dts, uint64_t pts, const char *data, size_t size,
|
||||
on_mk_frame_data_release cb, void *user_data, on_user_data_free user_data_free) {
|
||||
on_mk_frame_data_release cb, void *user_data, on_user_data_free user_data_free) {
|
||||
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
|
||||
switch (codec_id) {
|
||||
case CodecH264:
|
||||
case CodecH265:
|
||||
return mk_frame_create_complex(codec_id, dts, pts, 0, prefixSize(data, size), (char *)data, size, cb, std::move(ptr));
|
||||
|
||||
case CodecAAC: {
|
||||
int prefix = 0;
|
||||
if ((((uint8_t *) data)[0] == 0xFF && (((uint8_t *) data)[1] & 0xF0) == 0xF0) && size > ADTS_HEADER_LEN) {
|
||||
prefix = ADTS_HEADER_LEN;
|
||||
}
|
||||
return mk_frame_create_complex(codec_id, dts, pts, 0, prefix, (char *)data, size, cb, std::move(ptr));
|
||||
}
|
||||
|
||||
default:
|
||||
return mk_frame_create_complex(codec_id, dts, pts, 0, 0, (char *)data, size, cb, std::move(ptr));
|
||||
}
|
||||
return mk_frame_create_complex(codec_id, dts, pts, data, size, cb, std::move(ptr));
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_frame_unref(mk_frame frame) {
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
|
||||
#include "mk_h264_splitter.h"
|
||||
#include "Http/HttpRequestSplitter.h"
|
||||
#include "Extension/H264.h"
|
||||
#include "Extension/H265.h"
|
||||
#include "Extension/Factory.h"
|
||||
|
||||
using namespace mediakit;
|
||||
|
||||
@@ -28,8 +27,9 @@ protected:
|
||||
|
||||
private:
|
||||
bool _h265 = false;
|
||||
bool _have_decode_frame = false;
|
||||
onH264 _cb;
|
||||
size_t _search_pos = 0;
|
||||
toolkit::BufferLikeString _buffer;
|
||||
};
|
||||
|
||||
void H264Splitter::setOnSplitted(H264Splitter::onH264 cb) {
|
||||
@@ -43,11 +43,21 @@ H264Splitter::~H264Splitter() {
|
||||
}
|
||||
|
||||
ssize_t H264Splitter::onRecvHeader(const char *data, size_t len) {
|
||||
_cb(data, len);
|
||||
auto frame = Factory::getFrameFromPtr(_h265 ? CodecH265 : CodecH264, (char *)data, len, 0, 0);
|
||||
if (_have_decode_frame && (frame->decodeAble() || frame->configFrame())) {
|
||||
// 缓存中存在可解码帧,且下一帧是可解码帧或者配置帧,那么flush缓存
|
||||
_cb(_buffer.data(), _buffer.size());
|
||||
_buffer.assign(data, len);
|
||||
_have_decode_frame = frame->decodeAble();
|
||||
} else {
|
||||
// 还需要缓存
|
||||
_buffer.append(data, len);
|
||||
_have_decode_frame = _have_decode_frame || frame->decodeAble();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *onSearchPacketTail_l(const char *data, size_t len) {
|
||||
const char *H264Splitter::onSearchPacketTail(const char *data, size_t len) {
|
||||
for (size_t i = 2; len > 2 && i < len - 2; ++i) {
|
||||
//判断0x00 00 01
|
||||
if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 1) {
|
||||
@@ -61,28 +71,6 @@ static const char *onSearchPacketTail_l(const char *data, size_t len) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *H264Splitter::onSearchPacketTail(const char *data, size_t len) {
|
||||
auto last_frame = data + _search_pos;
|
||||
auto next_frame = onSearchPacketTail_l(last_frame, len - _search_pos);
|
||||
if (!next_frame) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto last_frame_len = next_frame - last_frame;
|
||||
Frame::Ptr frame;
|
||||
if (_h265) {
|
||||
frame = std::make_shared<H265FrameNoCacheAble>((char *) last_frame, last_frame_len, 0, 0, prefixSize(last_frame, last_frame_len));
|
||||
} else {
|
||||
frame = std::make_shared<H264FrameNoCacheAble>((char *) last_frame, last_frame_len, 0, 0, prefixSize(last_frame, last_frame_len));
|
||||
}
|
||||
if (frame->decodeAble()) {
|
||||
_search_pos = 0;
|
||||
return next_frame;
|
||||
}
|
||||
_search_pos += last_frame_len;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
API_EXPORT mk_h264_splitter API_CALL mk_h264_splitter_create(on_mk_h264_splitter_frame cb, void *user_data, int is_h265) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "mk_player.h"
|
||||
#include "Util/logger.h"
|
||||
#include "Player/MediaPlayer.h"
|
||||
#include "Extension/H264.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace toolkit;
|
||||
@@ -24,7 +23,6 @@ public:
|
||||
MediaPlayerForC(){
|
||||
_player = std::make_shared<MediaPlayer>();
|
||||
}
|
||||
~MediaPlayerForC() = default;
|
||||
|
||||
MediaPlayer *operator->(){
|
||||
return _player.get();
|
||||
|
||||
@@ -1,26 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
|
||||
#include "mk_proxyplayer.h"
|
||||
#include "Player/PlayerProxy.h"
|
||||
#include "mk_util.h"
|
||||
|
||||
using namespace toolkit;
|
||||
using namespace mediakit;
|
||||
|
||||
API_EXPORT mk_proxy_player API_CALL mk_proxy_player_create(const char *vhost, const char *app, const char *stream, int hls_enabled, int mp4_enabled) {
|
||||
return mk_proxy_player_create3(vhost, app, stream, hls_enabled, mp4_enabled,-1);
|
||||
}
|
||||
|
||||
API_EXPORT mk_proxy_player API_CALL mk_proxy_player_create2(const char *vhost, const char *app, const char *stream, mk_ini ini) {
|
||||
return mk_proxy_player_create4(vhost, app, stream, ini, -1);
|
||||
}
|
||||
|
||||
API_EXPORT mk_proxy_player API_CALL mk_proxy_player_create3(const char *vhost, const char *app, const char *stream, int hls_enabled, int mp4_enabled, int retry_count) {
|
||||
assert(vhost && app && stream);
|
||||
ProtocolOption option;
|
||||
option.enable_hls = hls_enabled;
|
||||
option.enable_mp4 = mp4_enabled;
|
||||
PlayerProxy::Ptr *obj(new PlayerProxy::Ptr(new PlayerProxy(vhost, app, stream, option)));
|
||||
return (mk_proxy_player) obj;
|
||||
PlayerProxy::Ptr *obj(new PlayerProxy::Ptr(new PlayerProxy(vhost, app, stream, option, retry_count)));
|
||||
return (mk_proxy_player)obj;
|
||||
}
|
||||
|
||||
|
||||
API_EXPORT mk_proxy_player API_CALL mk_proxy_player_create4(const char *vhost, const char *app, const char *stream, mk_ini ini, int retry_count) {
|
||||
assert(vhost && app && stream);
|
||||
ProtocolOption option(*((mINI *)ini));
|
||||
PlayerProxy::Ptr *obj(new PlayerProxy::Ptr(new PlayerProxy(vhost, app, stream, option, retry_count)));
|
||||
return (mk_proxy_player)obj;
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_proxy_player_release(mk_proxy_player ctx) {
|
||||
@@ -67,6 +84,20 @@ API_EXPORT void API_CALL mk_proxy_player_set_on_close2(mk_proxy_player ctx, on_m
|
||||
});
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_proxy_player_set_on_play_result(mk_proxy_player ctx, on_mk_proxy_player_close cb, void *user_data, on_user_data_free user_data_free) {
|
||||
assert(ctx);
|
||||
PlayerProxy::Ptr &obj = *((PlayerProxy::Ptr *)ctx);
|
||||
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
|
||||
obj->getPoller()->async([obj, cb, ptr]() {
|
||||
// 切换线程再操作
|
||||
obj->setPlayCallbackOnce([cb, ptr](const SockException &ex) {
|
||||
if (cb) {
|
||||
cb(ptr.get(), ex.getErrCode(), ex.what(), ex.getCustomCode());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
API_EXPORT int API_CALL mk_proxy_player_total_reader_count(mk_proxy_player ctx){
|
||||
assert(ctx);
|
||||
PlayerProxy::Ptr &obj = *((PlayerProxy::Ptr *) ctx);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
@@ -18,7 +18,13 @@ using namespace mediakit;
|
||||
|
||||
API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create(uint16_t port, int tcp_mode, const char *stream_id) {
|
||||
RtpServer::Ptr *server = new RtpServer::Ptr(new RtpServer);
|
||||
(*server)->start(port, stream_id, (RtpServer::TcpMode)tcp_mode);
|
||||
(*server)->start(port, MediaTuple { DEFAULT_VHOST, kRtpAppName, stream_id, "" }, (RtpServer::TcpMode)tcp_mode);
|
||||
return (mk_rtp_server)server;
|
||||
}
|
||||
|
||||
API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create2(uint16_t port, int tcp_mode, const char *vhost, const char *app, const char *stream_id) {
|
||||
RtpServer::Ptr *server = new RtpServer::Ptr(new RtpServer);
|
||||
(*server)->start(port, MediaTuple { vhost, app, stream_id, "" }, (RtpServer::TcpMode)tcp_mode);
|
||||
return (mk_rtp_server)server;
|
||||
}
|
||||
|
||||
@@ -56,7 +62,7 @@ API_EXPORT void API_CALL mk_rtp_server_set_on_detach2(mk_rtp_server ctx, on_mk_r
|
||||
RtpServer::Ptr *server = (RtpServer::Ptr *) ctx;
|
||||
if (cb) {
|
||||
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
|
||||
(*server)->setOnDetach([cb, ptr]() {
|
||||
(*server)->setOnDetach([cb, ptr](const SockException &ex) {
|
||||
cb(ptr.get());
|
||||
});
|
||||
} else {
|
||||
@@ -71,6 +77,11 @@ API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create(uint16_t port, int enable
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create2(uint16_t port, int tcp_mode, const char *vhost, const char *app, const char *stream_id) {
|
||||
WarnL << "请打开ENABLE_RTPPROXY后再编译";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_rtp_server_release(mk_rtp_server ctx) {
|
||||
WarnL << "请打开ENABLE_RTPPROXY后再编译";
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
@@ -33,9 +33,8 @@ private:
|
||||
|
||||
class SessionForC : public toolkit::Session {
|
||||
public:
|
||||
SessionForC(const toolkit::Socket::Ptr &pSock) ;
|
||||
~SessionForC() override = default;
|
||||
void onRecv(const toolkit::Buffer::Ptr &buffer) override ;
|
||||
SessionForC(const toolkit::Socket::Ptr &pSock);
|
||||
void onRecv(const toolkit::Buffer::Ptr &buffer) override;
|
||||
void onError(const toolkit::SockException &err) override;
|
||||
void onManager() override;
|
||||
std::shared_ptr<void> _user_data;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
@@ -80,8 +80,6 @@ public:
|
||||
_user_data = std::move(user_data);
|
||||
}
|
||||
|
||||
~TimerForC() = default;
|
||||
|
||||
uint64_t operator()(){
|
||||
lock_guard<recursive_mutex> lck(_mxt);
|
||||
if(!_cb){
|
||||
@@ -135,8 +133,6 @@ API_EXPORT void API_CALL mk_timer_release(mk_timer ctx){
|
||||
|
||||
class WorkThreadPoolForC : public TaskExecutorGetterImp {
|
||||
public:
|
||||
~WorkThreadPoolForC() override = default;
|
||||
|
||||
WorkThreadPoolForC(const char *name, size_t n_thread, int priority) {
|
||||
//最低优先级
|
||||
addPoller(name, n_thread, (ThreadPool::Priority) priority, false);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
@@ -27,8 +27,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
~VideoTrackForC() override = default;
|
||||
|
||||
int getVideoHeight() const override {
|
||||
return _args.video.height;
|
||||
}
|
||||
@@ -45,16 +43,16 @@ public:
|
||||
return _codec_id;
|
||||
}
|
||||
|
||||
bool ready() override {
|
||||
bool ready() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
Track::Ptr clone() override {
|
||||
auto track_in = std::shared_ptr<Track>(shared_from_this());
|
||||
Track::Ptr clone() const override {
|
||||
auto track_in = std::shared_ptr<Track>(const_cast<VideoTrackForC *>(this)->shared_from_this());
|
||||
return Factory::getTrackByAbstractTrack(track_in);
|
||||
}
|
||||
|
||||
Sdp::Ptr getSdp() override {
|
||||
Sdp::Ptr getSdp(uint8_t) const override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -65,17 +63,15 @@ private:
|
||||
|
||||
class AudioTrackForC : public AudioTrackImp, public std::enable_shared_from_this<AudioTrackForC> {
|
||||
public:
|
||||
~AudioTrackForC() override = default;
|
||||
|
||||
AudioTrackForC(int codec_id, codec_args *args) :
|
||||
AudioTrackImp((CodecId) codec_id, args->audio.sample_rate, args->audio.channels, 16) {}
|
||||
|
||||
Track::Ptr clone() override {
|
||||
auto track_in = std::shared_ptr<Track>(shared_from_this());
|
||||
Track::Ptr clone() const override {
|
||||
auto track_in = std::shared_ptr<Track>(const_cast<AudioTrackForC *>(this)->shared_from_this());
|
||||
return Factory::getTrackByAbstractTrack(track_in);
|
||||
}
|
||||
|
||||
Sdp::Ptr getSdp() override {
|
||||
Sdp::Ptr getSdp(uint8_t payload_type) const override {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
@@ -113,6 +109,21 @@ API_EXPORT int API_CALL mk_track_bit_rate(mk_track track) {
|
||||
return (*((Track::Ptr *) track))->getBitRate();
|
||||
}
|
||||
|
||||
API_EXPORT int API_CALL mk_track_ready(mk_track track) {
|
||||
assert(track);
|
||||
return (*((Track::Ptr *)track))->ready();
|
||||
}
|
||||
|
||||
API_EXPORT uint64_t API_CALL mk_track_frames(mk_track track) {
|
||||
assert(track);
|
||||
return (*((Track::Ptr *)track))->getFrames();
|
||||
}
|
||||
|
||||
API_EXPORT uint64_t API_CALL mk_track_duration(mk_track track) {
|
||||
assert(track);
|
||||
return (*((Track::Ptr *)track))->getDuration();
|
||||
}
|
||||
|
||||
API_EXPORT void *API_CALL mk_track_add_delegate(mk_track track, on_mk_frame_out cb, void *user_data) {
|
||||
return mk_track_add_delegate2(track, cb, user_data, nullptr);
|
||||
}
|
||||
@@ -171,6 +182,36 @@ API_EXPORT int API_CALL mk_track_video_fps(mk_track track) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
API_EXPORT uint64_t API_CALL mk_track_video_key_frames(mk_track track) {
|
||||
assert(track);
|
||||
auto video = dynamic_pointer_cast<VideoTrack>((*((Track::Ptr *)track)));
|
||||
if (video) {
|
||||
return video->getVideoFps();
|
||||
}
|
||||
WarnL << "not video track";
|
||||
return 0;
|
||||
}
|
||||
|
||||
API_EXPORT int API_CALL mk_track_video_gop_size(mk_track track) {
|
||||
assert(track);
|
||||
auto video = dynamic_pointer_cast<VideoTrack>((*((Track::Ptr *)track)));
|
||||
if (video) {
|
||||
return video->getVideoGopSize();
|
||||
}
|
||||
WarnL << "not video track";
|
||||
return 0;
|
||||
}
|
||||
|
||||
API_EXPORT int API_CALL mk_track_video_gop_interval_ms(mk_track track) {
|
||||
assert(track);
|
||||
auto video = dynamic_pointer_cast<VideoTrack>((*((Track::Ptr *)track)));
|
||||
if (video) {
|
||||
return video->getVideoGopInterval();
|
||||
}
|
||||
WarnL << "not video track";
|
||||
return 0;
|
||||
}
|
||||
|
||||
API_EXPORT int API_CALL mk_track_audio_sample_rate(mk_track track) {
|
||||
assert(track);
|
||||
auto audio = dynamic_pointer_cast<AudioTrack>((*((Track::Ptr *) track)));
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT license that can be found in the
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
@@ -15,16 +15,15 @@
|
||||
#include "Util/util.h"
|
||||
#include "Util/mini.h"
|
||||
#include "Util/logger.h"
|
||||
#include "Util/TimeTicker.h"
|
||||
#include "Poller/EventPoller.h"
|
||||
#include "Thread/WorkThreadPool.h"
|
||||
#include "Common/config.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace toolkit;
|
||||
using namespace mediakit;
|
||||
|
||||
#ifndef _WIN32
|
||||
#define _strdup strdup
|
||||
#endif
|
||||
|
||||
API_EXPORT void API_CALL mk_free(void *ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
@@ -65,7 +64,7 @@ API_EXPORT mk_ini API_CALL mk_ini_default() {
|
||||
static void emit_ini_file_reload(mk_ini ini) {
|
||||
if (ini == mk_ini_default()) {
|
||||
// 广播配置文件热加载
|
||||
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastReloadConfig);
|
||||
NOTICE_EMIT(BroadcastReloadConfigArgs, Broadcast::kBroadcastReloadConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +135,129 @@ API_EXPORT void API_CALL mk_ini_dump_file(mk_ini ini, const char *file) {
|
||||
ptr->dumpFile(file);
|
||||
}
|
||||
|
||||
extern uint64_t getTotalMemUsage();
|
||||
extern uint64_t getTotalMemBlock();
|
||||
extern uint64_t getThisThreadMemUsage();
|
||||
extern uint64_t getThisThreadMemBlock();
|
||||
extern std::vector<size_t> getBlockTypeSize();
|
||||
extern uint64_t getTotalMemBlockByType(int type);
|
||||
extern uint64_t getThisThreadMemBlockByType(int type);
|
||||
|
||||
namespace mediakit {
|
||||
class MediaSource;
|
||||
class MultiMediaSourceMuxer;
|
||||
class FrameImp;
|
||||
class Frame;
|
||||
class RtpPacket;
|
||||
class RtmpPacket;
|
||||
} // namespace mediakit
|
||||
|
||||
namespace toolkit {
|
||||
class TcpServer;
|
||||
class TcpSession;
|
||||
class UdpServer;
|
||||
class UdpSession;
|
||||
class TcpClient;
|
||||
class Socket;
|
||||
class Buffer;
|
||||
class BufferRaw;
|
||||
class BufferLikeString;
|
||||
class BufferList;
|
||||
} // namespace toolkit
|
||||
|
||||
API_EXPORT void API_CALL mk_get_statistic(on_mk_get_statistic_cb func, void *user_data, on_user_data_free free_cb) {
|
||||
assert(func);
|
||||
std::shared_ptr<void> data(user_data, free_cb);
|
||||
auto cb = [func, data](const toolkit::mINI &ini) { func(data.get(), (mk_ini)&ini); };
|
||||
auto obj = std::make_shared<toolkit::mINI>();
|
||||
auto &val = *obj;
|
||||
|
||||
val["object.MediaSource"] = ObjectStatistic<MediaSource>::count();
|
||||
val["object.MultiMediaSourceMuxer"] = ObjectStatistic<MultiMediaSourceMuxer>::count();
|
||||
|
||||
val["object.TcpServer"] = ObjectStatistic<TcpServer>::count();
|
||||
val["object.TcpSession"] = ObjectStatistic<TcpSession>::count();
|
||||
val["object.UdpServer"] = ObjectStatistic<UdpServer>::count();
|
||||
val["object.UdpSession"] = ObjectStatistic<UdpSession>::count();
|
||||
val["object.TcpClient"] = ObjectStatistic<TcpClient>::count();
|
||||
val["object.Socket"] = ObjectStatistic<Socket>::count();
|
||||
|
||||
val["object.FrameImp"] = ObjectStatistic<FrameImp>::count();
|
||||
val["object.Frame"] = ObjectStatistic<Frame>::count();
|
||||
|
||||
val["object.Buffer"] = ObjectStatistic<Buffer>::count();
|
||||
val["object.BufferRaw"] = ObjectStatistic<BufferRaw>::count();
|
||||
val["object.BufferLikeString"] = ObjectStatistic<BufferLikeString>::count();
|
||||
val["object.BufferList"] = ObjectStatistic<BufferList>::count();
|
||||
|
||||
val["object.RtpPacket"] = ObjectStatistic<RtpPacket>::count();
|
||||
val["object.RtmpPacket"] = ObjectStatistic<RtmpPacket>::count();
|
||||
#ifdef ENABLE_MEM_DEBUG
|
||||
auto bytes = getTotalMemUsage();
|
||||
val["memory.memUsage"] = bytes;
|
||||
val["memory.memUsageMB"] = (int)(bytes / 1024 / 1024);
|
||||
val["memory.memBlock"] = getTotalMemBlock();
|
||||
static auto block_type_size = getBlockTypeSize();
|
||||
{
|
||||
int i = 0;
|
||||
string str;
|
||||
size_t last = 0;
|
||||
for (auto sz : block_type_size) {
|
||||
str.append(to_string(last) + "~" + to_string(sz) + ":" + to_string(getTotalMemBlockByType(i++)) + ";");
|
||||
last = sz;
|
||||
}
|
||||
str.pop_back();
|
||||
val["memory.memBlockTypeCount"] = str;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto thread_size = EventPollerPool::Instance().getExecutorSize() + WorkThreadPool::Instance().getExecutorSize();
|
||||
std::shared_ptr<vector<toolkit::mINI>> thread_mem_info = std::make_shared<vector<toolkit::mINI>>(thread_size);
|
||||
|
||||
shared_ptr<void> finished(nullptr, [thread_mem_info, cb, obj](void *) {
|
||||
for (auto &val : *thread_mem_info) {
|
||||
auto thread_name = val["name"];
|
||||
replace(thread_name, "...", "~~~");
|
||||
auto prefix = "thread-" + thread_name + ".";
|
||||
for (auto &pr : val) {
|
||||
(*obj).emplace(prefix + pr.first, std::move(pr.second));
|
||||
}
|
||||
}
|
||||
// 触发回调
|
||||
cb(*obj);
|
||||
});
|
||||
|
||||
auto pos = 0;
|
||||
auto lambda = [&](const TaskExecutor::Ptr &executor) {
|
||||
auto &val = (*thread_mem_info)[pos++];
|
||||
val["load"] = executor->load();
|
||||
Ticker ticker;
|
||||
executor->async([finished, &val, ticker]() {
|
||||
val["name"] = getThreadName();
|
||||
val["delay"] = ticker.elapsedTime();
|
||||
#ifdef ENABLE_MEM_DEBUG
|
||||
auto bytes = getThisThreadMemUsage();
|
||||
val["memUsage"] = bytes;
|
||||
val["memUsageMB"] = bytes / 1024 / 1024;
|
||||
val["memBlock"] = getThisThreadMemBlock();
|
||||
{
|
||||
int i = 0;
|
||||
string str;
|
||||
size_t last = 0;
|
||||
for (auto sz : block_type_size) {
|
||||
str.append(to_string(last) + "~" + to_string(sz) + ":" + to_string(getThisThreadMemBlockByType(i++)) + ";");
|
||||
last = sz;
|
||||
}
|
||||
str.pop_back();
|
||||
val["memBlockTypeCount"] = str;
|
||||
}
|
||||
#endif
|
||||
});
|
||||
};
|
||||
EventPollerPool::Instance().for_each(lambda);
|
||||
WorkThreadPool::Instance().for_each(lambda);
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_log_printf(int level, const char *file, const char *function, int line, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
Reference in New Issue
Block a user