新增c sdk api,防止user_data导致的内存泄露

This commit is contained in:
ziyue 2023-02-11 15:14:18 +08:00
parent 5078723236
commit 2f090e33cf
29 changed files with 291 additions and 132 deletions

View File

@ -47,6 +47,9 @@ extern "C" {
//输出日志到回调函数(mk_events::on_mk_log)
#define LOG_CALLBACK (1 << 2)
//回调user_data回调函数
typedef void(API_CALL *on_user_data_free)(void *user_data);
typedef struct {
// 线程数
int thread_num;
@ -183,6 +186,9 @@ typedef void(API_CALL *on_mk_webrtc_get_answer_sdp)(void *user_data, const char
API_EXPORT void API_CALL mk_webrtc_get_answer_sdp(void *user_data, on_mk_webrtc_get_answer_sdp cb, const char *type,
const char *offer, const char *url);
API_EXPORT void API_CALL mk_webrtc_get_answer_sdp2(void *user_data, on_user_data_free user_data_free, on_mk_webrtc_get_answer_sdp cb, const char *type,
const char *offer, const char *url);
/**
* srt服务器
* @param port srt监听端口

View File

@ -120,6 +120,7 @@ typedef void(API_CALL *on_mk_media_source_send_rtp_result)(void *user_data, uint
//MediaSource::startSendRtp,请参考mk_media_start_send_rtp,注意ctx参数类型不一样
API_EXPORT void API_CALL mk_media_source_start_send_rtp(const mk_media_source ctx, const char *dst_url, uint16_t dst_port, const char *ssrc, int is_udp, on_mk_media_source_send_rtp_result cb, void *user_data);
API_EXPORT void API_CALL mk_media_source_start_send_rtp2(const mk_media_source ctx, const char *dst_url, uint16_t dst_port, const char *ssrc, int is_udp, on_mk_media_source_send_rtp_result cb, void *user_data, on_user_data_free user_data_free);
//MediaSource::stopSendRtp请参考mk_media_stop_send_rtp,注意ctx参数类型不一样
API_EXPORT int API_CALL mk_media_source_stop_send_rtp(const mk_media_source ctx);

View File

@ -57,7 +57,8 @@ typedef void(API_CALL *on_mk_frame_data_release)(void *user_data, char *ptr);
*/
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);
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);
/**
* frame对象
* @param frame

View File

@ -36,6 +36,7 @@ typedef void(API_CALL *on_mk_h264_splitter_frame)(void *user_data, mk_h264_split
* @return
*/
API_EXPORT mk_h264_splitter API_CALL mk_h264_splitter_create(on_mk_h264_splitter_frame cb, void *user_data, int is_h265);
API_EXPORT mk_h264_splitter API_CALL mk_h264_splitter_create2(on_mk_h264_splitter_frame cb, void *user_data, on_user_data_free user_data_free, int is_h265);
/**
* h264分帧器

View File

@ -51,7 +51,7 @@ API_EXPORT void API_CALL mk_http_downloader_release(mk_http_downloader ctx);
* @param user_data
*/
API_EXPORT void API_CALL mk_http_downloader_start(mk_http_downloader ctx, const char *url, const char *file, on_mk_download_complete cb, void *user_data);
API_EXPORT void API_CALL mk_http_downloader_start2(mk_http_downloader ctx, const char *url, const char *file, on_mk_download_complete cb, void *user_data, on_user_data_free user_data_free);
///////////////////////////////////////////HttpRequester/////////////////////////////////////////////
typedef void *mk_http_requester;
@ -143,6 +143,7 @@ API_EXPORT mk_parser API_CALL mk_http_requester_get_response(mk_http_requester c
* @param user_data
*/
API_EXPORT void API_CALL mk_http_requester_set_cb(mk_http_requester ctx,on_mk_http_requester_complete cb, void *user_data);
API_EXPORT void API_CALL mk_http_requester_set_cb2(mk_http_requester ctx,on_mk_http_requester_complete cb, void *user_data, on_user_data_free user_data_free);
/**
* url请求

View File

@ -183,6 +183,7 @@ typedef void(API_CALL *on_mk_media_close)(void *user_data);
* @param user_data
*/
API_EXPORT void API_CALL mk_media_set_on_close(mk_media ctx, on_mk_media_close cb, void *user_data);
API_EXPORT void API_CALL mk_media_set_on_close2(mk_media ctx, on_mk_media_close cb, void *user_data, on_user_data_free user_data_free);
/**
* seek请求时触发该回调
@ -213,6 +214,7 @@ typedef int(API_CALL* on_mk_media_speed)(void* user_data, float speed);
* @param user_data
*/
API_EXPORT void API_CALL mk_media_set_on_seek(mk_media ctx, on_mk_media_seek cb, void *user_data);
API_EXPORT void API_CALL mk_media_set_on_seek2(mk_media ctx, on_mk_media_seek cb, void *user_data, on_user_data_free user_data_free);
/**
* pause请求事件
@ -221,6 +223,7 @@ API_EXPORT void API_CALL mk_media_set_on_seek(mk_media ctx, on_mk_media_seek cb,
* @param user_data
*/
API_EXPORT void API_CALL mk_media_set_on_pause(mk_media ctx, on_mk_media_pause cb, void *user_data);
API_EXPORT void API_CALL mk_media_set_on_pause2(mk_media ctx, on_mk_media_pause cb, void *user_data, on_user_data_free user_data_free);
/**
* pause请求事件
@ -229,6 +232,7 @@ API_EXPORT void API_CALL mk_media_set_on_pause(mk_media ctx, on_mk_media_pause c
* @param user_data
*/
API_EXPORT void API_CALL mk_media_set_on_speed(mk_media ctx, on_mk_media_speed cb, void *user_data);
API_EXPORT void API_CALL mk_media_set_on_speed2(mk_media ctx, on_mk_media_speed cb, void *user_data, on_user_data_free user_data_free);
/**
*
@ -252,6 +256,7 @@ typedef void(API_CALL *on_mk_media_source_regist)(void *user_data, mk_media_sour
* @param user_data
*/
API_EXPORT void API_CALL mk_media_set_on_regist(mk_media ctx, on_mk_media_source_regist cb, void *user_data);
API_EXPORT void API_CALL mk_media_set_on_regist2(mk_media ctx, on_mk_media_source_regist cb, void *user_data, on_user_data_free user_data_free);
/**
* rtp推流成功与否的回调()
@ -269,6 +274,7 @@ typedef on_mk_media_source_send_rtp_result on_mk_media_send_rtp_result;
* @param user_data
*/
API_EXPORT void API_CALL mk_media_start_send_rtp(mk_media ctx, const char *dst_url, uint16_t dst_port, const char *ssrc, int is_udp, on_mk_media_send_rtp_result cb, void *user_data);
API_EXPORT void API_CALL mk_media_start_send_rtp2(mk_media ctx, const char *dst_url, uint16_t dst_port, const char *ssrc, int is_udp, on_mk_media_send_rtp_result cb, void *user_data, on_user_data_free user_data_free);
/**
* ps-rtp发送api线程安全

View File

@ -94,6 +94,7 @@ API_EXPORT void API_CALL mk_player_seekto_pos(mk_player ctx, int seek_pos);
* @param user_data
*/
API_EXPORT void API_CALL mk_player_set_on_result(mk_player ctx, on_mk_play_event cb, void *user_data);
API_EXPORT void API_CALL mk_player_set_on_result2(mk_player ctx, on_mk_play_event cb, void *user_data, on_user_data_free user_data_free);
/**
*
@ -102,6 +103,7 @@ API_EXPORT void API_CALL mk_player_set_on_result(mk_player ctx, on_mk_play_event
* @param user_data
*/
API_EXPORT void API_CALL mk_player_set_on_shutdown(mk_player ctx, on_mk_play_event cb, void *user_data);
API_EXPORT void API_CALL mk_player_set_on_shutdown2(mk_player ctx, on_mk_play_event cb, void *user_data, on_user_data_free user_data_free);
///////////////////////////获取音视频相关信息接口在播放成功回调触发后才有效///////////////////////////////

View File

@ -70,6 +70,7 @@ typedef void(API_CALL *on_mk_proxy_player_close)(void *user_data, int err, const
* @param user_data
*/
API_EXPORT void API_CALL mk_proxy_player_set_on_close(mk_proxy_player ctx, on_mk_proxy_player_close cb, void *user_data);
API_EXPORT void API_CALL mk_proxy_player_set_on_close2(mk_proxy_player ctx, on_mk_proxy_player_close cb, void *user_data, on_user_data_free user_data_free);
/**
*

View File

@ -79,6 +79,7 @@ API_EXPORT void API_CALL mk_pusher_publish(mk_pusher ctx,const char *url);
* @param user_data
*/
API_EXPORT void API_CALL mk_pusher_set_on_result(mk_pusher ctx, on_mk_push_event cb, void *user_data);
API_EXPORT void API_CALL mk_pusher_set_on_result2(mk_pusher ctx, on_mk_push_event cb, void *user_data, on_user_data_free user_data_free);
/**
*
@ -87,6 +88,7 @@ API_EXPORT void API_CALL mk_pusher_set_on_result(mk_pusher ctx, on_mk_push_event
* @param user_data
*/
API_EXPORT void API_CALL mk_pusher_set_on_shutdown(mk_pusher ctx, on_mk_push_event cb, void *user_data);
API_EXPORT void API_CALL mk_pusher_set_on_shutdown2(mk_pusher ctx, on_mk_push_event cb, void *user_data, on_user_data_free user_data_free);
#ifdef __cplusplus
}

View File

@ -40,6 +40,7 @@ typedef void(API_CALL *on_mk_rtp_server_connected)(void *user_data, int err, con
* @return
*/
API_EXPORT void API_CALL mk_rtp_server_connect(mk_rtp_server ctx, const char *dst_url, uint16_t dst_port, on_mk_rtp_server_connected cb, void *user_data);
API_EXPORT void API_CALL mk_rtp_server_connect2(mk_rtp_server ctx, const char *dst_url, uint16_t dst_port, on_mk_rtp_server_connected cb, void *user_data, on_user_data_free user_data_free);
/**
* GB28181 RTP
@ -67,7 +68,7 @@ typedef void(API_CALL *on_mk_rtp_server_detach)(void *user_data);
* @param user_data
*/
API_EXPORT void API_CALL mk_rtp_server_set_on_detach(mk_rtp_server ctx, on_mk_rtp_server_detach cb, void *user_data);
API_EXPORT void API_CALL mk_rtp_server_set_on_detach2(mk_rtp_server ctx, on_mk_rtp_server_detach cb, void *user_data, on_user_data_free user_data_free);
#ifdef __cplusplus
}

View File

@ -31,6 +31,7 @@ typedef void(API_CALL *on_mk_buffer_free)(void *user_data, void *data);
* @return buffer对象
*/
API_EXPORT mk_buffer API_CALL mk_buffer_from_char(const char *data, size_t len, on_mk_buffer_free cb, void *user_data);
API_EXPORT mk_buffer API_CALL mk_buffer_from_char2(const char *data, size_t len, on_mk_buffer_free cb, void *user_data, on_user_data_free user_data_free);
API_EXPORT mk_buffer API_CALL mk_buffer_ref(mk_buffer buffer);
API_EXPORT void API_CALL mk_buffer_unref(mk_buffer buffer);
API_EXPORT const char* API_CALL mk_buffer_get_data(mk_buffer buffer);
@ -142,6 +143,7 @@ typedef enum {
* @param user_data
*/
API_EXPORT void API_CALL mk_tcp_session_set_user_data(mk_tcp_session session, void *user_data);
API_EXPORT void API_CALL mk_tcp_session_set_user_data2(mk_tcp_session session, void *user_data, on_user_data_free user_data_free);
/**
* tcp会话对象上附着的用户数据
@ -251,6 +253,7 @@ API_EXPORT void API_CALL mk_tcp_client_send_buffer_safe(mk_tcp_client ctx, mk_bu
* @param user_data
*/
API_EXPORT void API_CALL mk_tcp_client_set_user_data(mk_tcp_client ctx, void *user_data);
API_EXPORT void API_CALL mk_tcp_client_set_user_data2(mk_tcp_client ctx, void *user_data, on_user_data_free user_data_free);
/**
*

View File

@ -87,6 +87,7 @@ typedef void (API_CALL *on_mk_async)(void *user_data);
* @param user_data
*/
API_EXPORT void API_CALL mk_async_do(mk_thread ctx, on_mk_async cb, void *user_data);
API_EXPORT void API_CALL mk_async_do2(mk_thread ctx, on_mk_async cb, void *user_data, on_user_data_free user_data_free);
/**
* 线
@ -96,6 +97,7 @@ API_EXPORT void API_CALL mk_async_do(mk_thread ctx, on_mk_async cb, void *user_d
* @param user_data
*/
API_EXPORT void API_CALL mk_async_do_delay(mk_thread ctx, size_t ms, on_mk_async cb, void *user_data);
API_EXPORT void API_CALL mk_async_do_delay2(mk_thread ctx, size_t ms, on_mk_async cb, void *user_data, on_user_data_free user_data_free);
/**
* 线
@ -123,6 +125,7 @@ typedef uint64_t (API_CALL *on_mk_timer)(void *user_data);
* @return
*/
API_EXPORT mk_timer API_CALL mk_timer_create(mk_thread ctx, uint64_t delay_ms, on_mk_timer cb, void *user_data);
API_EXPORT mk_timer API_CALL mk_timer_create2(mk_thread ctx, uint64_t delay_ms, on_mk_timer cb, void *user_data, on_user_data_free user_data_free);
/**
*

View File

@ -80,6 +80,7 @@ API_EXPORT int API_CALL mk_track_bit_rate(mk_track track);
* @param user_data frame输出回调用户指针参数
*/
API_EXPORT void *API_CALL mk_track_add_delegate(mk_track track, on_mk_frame_out cb, void *user_data);
API_EXPORT void *API_CALL mk_track_add_delegate2(mk_track track, on_mk_frame_out cb, void *user_data, on_user_data_free user_data_free);
/**
* frame输出事件监听

View File

@ -78,6 +78,7 @@ API_EXPORT void API_CALL mk_decoder_set_max_async_frame_size(mk_decoder ctx, siz
* @param user_data
*/
API_EXPORT void API_CALL mk_decoder_set_cb(mk_decoder ctx, on_mk_decode cb, void *user_data);
API_EXPORT void API_CALL mk_decoder_set_cb2(mk_decoder ctx, on_mk_decode cb, void *user_data, on_user_data_free user_data_free);
/**
* FFmpeg原始AVCodecContext对象

View File

@ -296,17 +296,22 @@ private:
API_EXPORT void API_CALL mk_webrtc_get_answer_sdp(void *user_data, on_mk_webrtc_get_answer_sdp cb, const char *type,
const char *offer, const char *url) {
mk_webrtc_get_answer_sdp2(user_data, nullptr, cb, type, offer, url);
}
API_EXPORT void API_CALL mk_webrtc_get_answer_sdp2(void *user_data, on_user_data_free user_data_free, on_mk_webrtc_get_answer_sdp cb, const char *type,
const char *offer, const char *url) {
#ifdef ENABLE_WEBRTC
assert(type && offer && url && cb);
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, user_data, cb](const WebRtcInterface &exchanger) mutable {
[offer_str, session, ptr, cb](const WebRtcInterface &exchanger) mutable {
try {
auto sdp_answer = const_cast<WebRtcInterface &>(exchanger).getAnswerSdp(offer_str);
cb(user_data, sdp_answer.data(), nullptr);
cb(ptr.get(), sdp_answer.data(), nullptr);
} catch (std::exception &ex) {
cb(user_data, nullptr, ex.what());
cb(ptr.get(), nullptr, ex.what());
}
});
#else

View File

@ -208,8 +208,11 @@ API_EXPORT int API_CALL mk_media_source_seek_to(const mk_media_source ctx,uint32
MediaSource *src = (MediaSource *)ctx;
return src->seekTo(stamp);
}
API_EXPORT void API_CALL mk_media_source_start_send_rtp(const mk_media_source ctx, const char *dst_url, uint16_t dst_port, const char *ssrc, int is_udp, on_mk_media_source_send_rtp_result cb, void *user_data) {
mk_media_source_start_send_rtp2(ctx, dst_url, dst_port, ssrc, is_udp, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_media_source_start_send_rtp2(const mk_media_source ctx, const char *dst_url, uint16_t dst_port, const char *ssrc, int is_udp, on_mk_media_source_send_rtp_result cb, void *user_data, on_user_data_free user_data_free){
assert(ctx && dst_url && ssrc);
MediaSource *src = (MediaSource *)ctx;
@ -219,9 +222,10 @@ API_EXPORT void API_CALL mk_media_source_start_send_rtp(const mk_media_source ct
args.ssrc = ssrc;
args.is_udp = is_udp;
src->startSendRtp(args, [cb, user_data](uint16_t local_port, const SockException &ex){
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
src->startSendRtp(args, [cb, ptr](uint16_t local_port, const SockException &ex){
if (cb) {
cb(user_data, local_port, ex.getErrCode(), ex.what());
cb(ptr.get(), local_port, ex.getErrCode(), ex.what());
}
});
}

View File

@ -27,17 +27,17 @@ public:
using Ptr = std::shared_ptr<FrameFromPtrForC>;
template<typename ...ARGS>
FrameFromPtrForC(bool cache_able, uint32_t flags, on_mk_frame_data_release cb, void *user_data, ARGS &&...args) : FrameFromPtr(
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;
_cb = cb;
_user_data = user_data;
_user_data = std::move(user_data);
_cache_able = cache_able;
}
~FrameFromPtrForC() override {
if (_cb) {
_cb(_user_data, _ptr);
_cb(_user_data.get(), _ptr);
}
}
@ -66,43 +66,47 @@ public:
private:
uint32_t _flags;
on_mk_frame_data_release _cb;
void *_user_data;
std::shared_ptr<void> _user_data;
bool _cache_able;
};
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, void *user_data) {
char *data, size_t size, on_mk_frame_data_release cb, std::shared_ptr<void> user_data) {
switch (codec_id) {
case CodecH264:
return new Frame::Ptr(new H264FrameHelper<FrameFromPtrForC>(cb, frame_flags, cb, user_data, (CodecId) codec_id,
data, size, dts, pts, prefix_size));
return 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 new Frame::Ptr(new H265FrameHelper<FrameFromPtrForC>(cb, frame_flags, cb, user_data, (CodecId) codec_id,
data, size, dts, pts, prefix_size));
return 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 new Frame::Ptr(new FrameFromPtrForC(cb, frame_flags, cb, user_data, (CodecId) codec_id, data,
size, dts, pts, prefix_size));
return new Frame::Ptr(new FrameFromPtrForC(
cb, frame_flags, cb, std::move(user_data), (CodecId)codec_id, data, size, dts, pts, prefix_size));
}
}
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) {
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) {
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, user_data);
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, user_data);
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, user_data);
return mk_frame_create_complex(codec_id, dts, pts, 0, 0, (char *)data, size, cb, std::move(ptr));
}
}

View File

@ -86,12 +86,17 @@ const char *H264Splitter::onSearchPacketTail(const char *data, size_t len) {
////////////////////////////////////////////////////////////////////////////////////////////////////////
API_EXPORT mk_h264_splitter API_CALL mk_h264_splitter_create(on_mk_h264_splitter_frame cb, void *user_data, int is_h265) {
return mk_h264_splitter_create2(cb, user_data, nullptr, is_h265);
}
API_EXPORT mk_h264_splitter API_CALL mk_h264_splitter_create2(on_mk_h264_splitter_frame cb, void *user_data, on_user_data_free user_data_free, int is_h265) {
assert(cb);
auto ptr = new H264Splitter(is_h265);
ptr->setOnSplitted([cb, ptr, user_data](const char *data, size_t len) {
cb(user_data, reinterpret_cast<mk_h264_splitter>(ptr), data, len);
auto ret = new H264Splitter(is_h265);
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
ret->setOnSplitted([cb, ptr, ret](const char *data, size_t len) {
cb(ptr.get(), reinterpret_cast<mk_h264_splitter>(ret), data, len);
});
return reinterpret_cast<mk_h264_splitter>(ptr);
return reinterpret_cast<mk_h264_splitter>(ret);
}
API_EXPORT void API_CALL mk_h264_splitter_release(mk_h264_splitter ctx){

View File

@ -30,17 +30,21 @@ API_EXPORT void API_CALL mk_http_downloader_release(mk_http_downloader ctx) {
}
API_EXPORT void API_CALL mk_http_downloader_start(mk_http_downloader ctx, const char *url, const char *file, on_mk_download_complete cb, void *user_data) {
mk_http_downloader_start2(ctx, url, file, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_http_downloader_start2(mk_http_downloader ctx, const char *url, const char *file, on_mk_download_complete cb, void *user_data, on_user_data_free user_data_free) {
assert(ctx && url && file);
HttpDownloader::Ptr *obj = (HttpDownloader::Ptr *) ctx;
(*obj)->setOnResult([cb, user_data](const SockException &ex, const string &filePath) {
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
(*obj)->setOnResult([cb, ptr](const SockException &ex, const string &filePath) {
if (cb) {
cb(user_data, ex.getErrCode(), ex.what(), filePath.data());
cb(ptr.get(), ex.getErrCode(), ex.what(), filePath.data());
}
});
(*obj)->startDownload(url, file, false);
}
///////////////////////////////////////////HttpRequester/////////////////////////////////////////////
API_EXPORT mk_http_requester API_CALL mk_http_requester_create(){
HttpRequester::Ptr *ret = new HttpRequester::Ptr(new HttpRequester);
@ -129,10 +133,15 @@ API_EXPORT mk_parser API_CALL mk_http_requester_get_response(mk_http_requester c
}
API_EXPORT void API_CALL mk_http_requester_set_cb(mk_http_requester ctx,on_mk_http_requester_complete cb, void *user_data) {
mk_http_requester_set_cb2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_http_requester_set_cb2(mk_http_requester ctx,on_mk_http_requester_complete cb, void *user_data, on_user_data_free user_data_free) {
assert(ctx && cb);
HttpRequester::Ptr *obj = (HttpRequester::Ptr *)ctx;
(*obj)->setOnResult([cb, user_data](const SockException &ex, const Parser &res) {
cb(user_data, ex.getErrCode(), ex.what());
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
(*obj)->setOnResult([cb, ptr](const SockException &ex, const Parser &res) {
cb(ptr.get(), ex.getErrCode(), ex.what());
});
}

View File

@ -23,7 +23,8 @@ public:
MediaHelper(ArgsType &&...args){
_channel = std::make_shared<DevChannel>(std::forward<ArgsType>(args)...);
}
~MediaHelper(){}
~MediaHelper() = default;
void attachEvent(){
_channel->setMediaListener(shared_from_this());
@ -33,29 +34,29 @@ public:
return _channel;
}
void setOnClose(on_mk_media_close cb, void *user_data){
void setOnClose(on_mk_media_close cb, std::shared_ptr<void> user_data){
_on_close = cb;
_on_close_data = user_data;
_on_close_data = std::move(user_data);
}
void setOnSeek(on_mk_media_seek cb, void *user_data){
void setOnSeek(on_mk_media_seek cb, std::shared_ptr<void> user_data){
_on_seek = cb;
_on_seek_data = user_data;
_on_seek_data = std::move(user_data);
}
void setOnPause(on_mk_media_pause cb, void* user_data) {
void setOnPause(on_mk_media_pause cb, std::shared_ptr<void> user_data) {
_on_pause = cb;
_on_pause_data = user_data;
_on_pause_data = std::move(user_data);
}
void setOnSpeed(on_mk_media_speed cb, void* user_data) {
void setOnSpeed(on_mk_media_speed cb, std::shared_ptr<void> user_data) {
_on_speed = cb;
_on_speed_data = user_data;
_on_speed_data = std::move(user_data);
}
void setOnRegist(on_mk_media_source_regist cb, void *user_data){
void setOnRegist(on_mk_media_source_regist cb, std::shared_ptr<void> user_data){
_on_regist = cb;
_on_regist_data = user_data;
_on_regist_data = std::move(user_data);
}
protected:
@ -67,7 +68,7 @@ protected:
return false;
}
//请在回调中调用mk_media_release函数释放资源,否则MediaSource::close()操作不会生效
_on_close(_on_close_data);
_on_close(_on_close_data.get());
WarnL << "close media: " << sender.getUrl();
return true;
}
@ -76,7 +77,7 @@ protected:
if (!_on_seek) {
return false;
}
return _on_seek(_on_seek_data, stamp);
return _on_seek(_on_seek_data.get(), stamp);
}
// 通知暂停或恢复
@ -84,7 +85,7 @@ protected:
if (!_on_pause) {
return false;
}
return _on_pause(_on_pause_data, pause);
return _on_pause(_on_pause_data.get(), pause);
}
//通知倍数播放
@ -92,12 +93,12 @@ protected:
if (!_on_speed) {
return false;
}
return _on_speed(_on_speed_data, speed);
return _on_speed(_on_speed_data.get(), speed);
}
void onRegist(MediaSource &sender, bool regist) override{
if (_on_regist) {
_on_regist(_on_regist_data, &sender, regist);
_on_regist(_on_regist_data.get(), &sender, regist);
}
}
@ -108,41 +109,66 @@ private:
on_mk_media_pause _on_pause = nullptr;
on_mk_media_speed _on_speed = nullptr;
on_mk_media_source_regist _on_regist = nullptr;
void* _on_seek_data;
void* _on_pause_data;
void* _on_speed_data;
void *_on_close_data;
void *_on_regist_data;
std::shared_ptr<void> _on_seek_data;
std::shared_ptr<void> _on_pause_data;
std::shared_ptr<void> _on_speed_data;
std::shared_ptr<void> _on_close_data;
std::shared_ptr<void> _on_regist_data;
};
API_EXPORT void API_CALL mk_media_set_on_close(mk_media ctx, on_mk_media_close cb, void *user_data){
mk_media_set_on_close2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_media_set_on_close2(mk_media ctx, on_mk_media_close cb, void *user_data, on_user_data_free user_data_free) {
assert(ctx);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->setOnClose(cb, user_data);
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
(*obj)->setOnClose(cb, std::move(ptr));
}
API_EXPORT void API_CALL mk_media_set_on_seek(mk_media ctx, on_mk_media_seek cb, void *user_data) {
mk_media_set_on_seek2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_media_set_on_seek2(mk_media ctx, on_mk_media_seek cb, void *user_data, on_user_data_free user_data_free) {
assert(ctx);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->setOnSeek(cb, user_data);
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
(*obj)->setOnSeek(cb, std::move(ptr));
}
API_EXPORT void API_CALL mk_media_set_on_pause(mk_media ctx, on_mk_media_pause cb, void *user_data) {
mk_media_set_on_pause2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_media_set_on_pause2(mk_media ctx, on_mk_media_pause cb, void *user_data, on_user_data_free user_data_free) {
assert(ctx);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->setOnPause(cb, user_data);
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
(*obj)->setOnPause(cb, std::move(ptr));
}
API_EXPORT void API_CALL mk_media_set_on_speed(mk_media ctx, on_mk_media_speed cb, void *user_data) {
mk_media_set_on_speed2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_media_set_on_speed2(mk_media ctx, on_mk_media_speed cb, void *user_data, on_user_data_free user_data_free){
assert(ctx);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->setOnSpeed(cb, user_data);
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
(*obj)->setOnSpeed(cb, std::move(ptr));
}
API_EXPORT void API_CALL mk_media_set_on_regist(mk_media ctx, on_mk_media_source_regist cb, void *user_data){
mk_media_set_on_regist2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_media_set_on_regist2(mk_media ctx, on_mk_media_source_regist cb, void *user_data, on_user_data_free user_data_free) {
assert(ctx);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->setOnRegist(cb, user_data);
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
(*obj)->setOnRegist(cb, std::move(ptr));
}
API_EXPORT int API_CALL mk_media_total_reader_count(mk_media ctx){
@ -255,6 +281,10 @@ API_EXPORT int API_CALL mk_media_input_audio(mk_media ctx, const void* data, int
}
API_EXPORT void API_CALL mk_media_start_send_rtp(mk_media ctx, const char *dst_url, uint16_t dst_port, const char *ssrc, int is_udp, on_mk_media_send_rtp_result cb, void *user_data) {
mk_media_start_send_rtp2(ctx, dst_url, dst_port, ssrc, is_udp, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_media_start_send_rtp2(mk_media ctx, const char *dst_url, uint16_t dst_port, const char *ssrc, int is_udp, on_mk_media_send_rtp_result cb, void *user_data, on_user_data_free user_data_free){
assert(ctx && dst_url && ssrc);
MediaHelper::Ptr* obj = (MediaHelper::Ptr*) ctx;
@ -266,10 +296,11 @@ API_EXPORT void API_CALL mk_media_start_send_rtp(mk_media ctx, const char *dst_u
// sender参数无用
auto ref = *obj;
(*obj)->getChannel()->getOwnerPoller(MediaSource::NullMediaSource())->async([args, ref, cb, user_data]() {
ref->getChannel()->startSendRtp(MediaSource::NullMediaSource(), args, [cb, user_data](uint16_t local_port, const SockException &ex) {
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
(*obj)->getChannel()->getOwnerPoller(MediaSource::NullMediaSource())->async([args, ref, cb, ptr]() {
ref->getChannel()->startSendRtp(MediaSource::NullMediaSource(), args, [cb, ptr](uint16_t local_port, const SockException &ex) {
if (cb) {
cb(user_data, local_port, ex.getErrCode(), ex.what());
cb(ptr.get(), local_port, ex.getErrCode(), ex.what());
}
});
});

View File

@ -61,7 +61,7 @@ public:
if (is_shutdown) {
//播放中断
if (_on_shutdown) {
_on_shutdown(_on_shutdown_data, ex.getErrCode(), ex.what(), nullptr, 0);
_on_shutdown(_on_shutdown_data.get(), ex.getErrCode(), ex.what(), nullptr, 0);
}
return;
}
@ -74,17 +74,17 @@ public:
for (auto &track : cpp_tracks) {
tracks[track_count++] = (mk_track) &track;
}
_on_play(_on_play_data, ex.getErrCode(), ex.what(), tracks, track_count);
_on_play(_on_play_data.get(), ex.getErrCode(), ex.what(), tracks, track_count);
}
}
void setOnEvent(on_mk_play_event cb, void *user_data, int type) {
void setOnEvent(on_mk_play_event cb, std::shared_ptr<void> user_data, int type) {
lock_guard<recursive_mutex> lck(_mtx);
if (type == 0) {
_on_play_data = user_data;
_on_play_data = std::move(user_data);
_on_play = cb;
} else {
_on_shutdown_data = user_data;
_on_shutdown_data = std::move(user_data);
_on_shutdown = cb;
}
}
@ -98,8 +98,8 @@ private:
on_mk_play_event _on_play = nullptr;
on_mk_play_event _on_shutdown = nullptr;
void *_on_play_data = nullptr;
void *_on_shutdown_data = nullptr;
std::shared_ptr<void> _on_play_data;
std::shared_ptr<void> _on_shutdown_data;
};
API_EXPORT mk_player API_CALL mk_player_create() {
@ -175,18 +175,28 @@ API_EXPORT void API_CALL mk_player_seekto_pos(mk_player ctx, int seek_pos) {
});
}
static void mk_player_set_on_event(mk_player ctx, on_mk_play_event cb, void *user_data, int type) {
static void mk_player_set_on_event(mk_player ctx, on_mk_play_event cb, std::shared_ptr<void> user_data, int type) {
assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
obj.setOnEvent(cb,user_data, type);
obj.setOnEvent(cb, std::move(user_data), type);
}
API_EXPORT void API_CALL mk_player_set_on_result(mk_player ctx, on_mk_play_event cb, void *user_data) {
mk_player_set_on_event(ctx,cb,user_data,0);
mk_player_set_on_result2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_player_set_on_result2(mk_player ctx, on_mk_play_event 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 *) {});
mk_player_set_on_event(ctx, cb, std::move(ptr), 0);
}
API_EXPORT void API_CALL mk_player_set_on_shutdown(mk_player ctx, on_mk_play_event cb, void *user_data) {
mk_player_set_on_event(ctx,cb,user_data,1);
mk_player_set_on_shutdown2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_player_set_on_shutdown2(mk_player ctx, on_mk_play_event 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 *) {});
mk_player_set_on_event(ctx, cb, std::move(ptr), 1);
}
API_EXPORT float API_CALL mk_player_duration(mk_player ctx) {

View File

@ -50,13 +50,18 @@ API_EXPORT void API_CALL mk_proxy_player_play(mk_proxy_player ctx, const char *u
}
API_EXPORT void API_CALL mk_proxy_player_set_on_close(mk_proxy_player ctx, on_mk_proxy_player_close cb, void *user_data){
mk_proxy_player_set_on_close2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_proxy_player_set_on_close2(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);
obj->getPoller()->async([obj,cb,user_data](){
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
obj->getPoller()->async([obj, cb, ptr]() {
// 切换线程再操作
obj->setOnClose([cb,user_data](const SockException &ex){
obj->setOnClose([cb, ptr](const SockException &ex) {
if (cb) {
cb(user_data, ex.getErrCode(), ex.what(), ex.getCustomCode());
cb(ptr.get(), ex.getErrCode(), ex.what(), ex.getCustomCode());
}
});
});

View File

@ -55,23 +55,29 @@ API_EXPORT void API_CALL mk_pusher_publish(mk_pusher ctx,const char *url){
}
API_EXPORT void API_CALL mk_pusher_set_on_result(mk_pusher ctx, on_mk_push_event cb, void *user_data){
mk_pusher_set_on_result2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_pusher_set_on_result2(mk_pusher ctx, on_mk_push_event cb, void *user_data, on_user_data_free user_data_free) {
assert(ctx && cb);
MediaPusher::Ptr &obj = *((MediaPusher::Ptr *)ctx);
obj->getPoller()->async([obj,cb,user_data](){
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
obj->getPoller()->async([obj, cb, ptr]() {
// 切换线程再操作
obj->setOnPublished([cb,user_data](const SockException &ex){
cb(user_data,ex.getErrCode(),ex.what());
});
obj->setOnPublished([cb, ptr](const SockException &ex) { cb(ptr.get(), ex.getErrCode(), ex.what()); });
});
}
API_EXPORT void API_CALL mk_pusher_set_on_shutdown(mk_pusher ctx, on_mk_push_event cb, void *user_data){
mk_pusher_set_on_shutdown2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_pusher_set_on_shutdown2(mk_pusher ctx, on_mk_push_event cb, void *user_data, on_user_data_free user_data_free) {
assert(ctx && cb);
MediaPusher::Ptr &obj = *((MediaPusher::Ptr *)ctx);
obj->getPoller()->async([obj,cb,user_data](){
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
obj->getPoller()->async([obj, cb, ptr]() {
// 切换线程再操作
obj->setOnShutdown([cb,user_data](const SockException &ex){
cb(user_data,ex.getErrCode(),ex.what());
});
obj->setOnShutdown([cb, ptr](const SockException &ex) { cb(ptr.get(), ex.getErrCode(), ex.what()); });
});
}

View File

@ -23,11 +23,16 @@ API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create(uint16_t port, int tcp_mo
}
API_EXPORT void API_CALL mk_rtp_server_connect(mk_rtp_server ctx, const char *dst_url, uint16_t dst_port, on_mk_rtp_server_connected cb, void *user_data) {
mk_rtp_server_connect2(ctx, dst_url, dst_port, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_rtp_server_connect2(mk_rtp_server ctx, const char *dst_url, uint16_t dst_port, on_mk_rtp_server_connected cb, void *user_data, on_user_data_free user_data_free){
RtpServer::Ptr *server = (RtpServer::Ptr *)ctx;
if (server) {
(*server)->connectToServer(dst_url, dst_port, [cb, user_data](const SockException &ex) {
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
(*server)->connectToServer(dst_url, dst_port, [cb, ptr](const SockException &ex) {
if (cb) {
cb(user_data, ex.getErrCode(), ex.what(), ex.getCustomCode());
cb(ptr.get(), ex.getErrCode(), ex.what(), ex.getCustomCode());
}
});
}
@ -44,10 +49,15 @@ API_EXPORT uint16_t API_CALL mk_rtp_server_port(mk_rtp_server ctx) {
}
API_EXPORT void API_CALL mk_rtp_server_set_on_detach(mk_rtp_server ctx, on_mk_rtp_server_detach cb, void *user_data) {
mk_rtp_server_set_on_detach2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_rtp_server_set_on_detach2(mk_rtp_server ctx, on_mk_rtp_server_detach cb, void *user_data, on_user_data_free user_data_free){
RtpServer::Ptr *server = (RtpServer::Ptr *) ctx;
if (cb) {
(*server)->setOnDetach([cb, user_data]() {
cb(user_data);
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
(*server)->setOnDetach([cb, ptr]() {
cb(ptr.get());
});
} else {
(*server)->setOnDetach(nullptr);

View File

@ -20,7 +20,7 @@ using namespace mediakit;
class BufferForC : public Buffer {
public:
BufferForC(const char *data, size_t len, on_mk_buffer_free cb, void *user_data) {
BufferForC(const char *data, size_t len, on_mk_buffer_free cb, std::shared_ptr<void> user_data) {
if (len <= 0) {
len = strlen(data);
}
@ -36,11 +36,11 @@ public:
_data = (char *) data;
_size = len;
_cb = cb;
_user_data = user_data;
_user_data = std::move(user_data);
}
~BufferForC() override {
_cb(_user_data, _data);
_cb(_user_data.get(), _data);
}
char *data() const override {
@ -55,12 +55,17 @@ private:
char *_data;
size_t _size;
on_mk_buffer_free _cb;
void *_user_data;
std::shared_ptr<void> _user_data;
};
API_EXPORT mk_buffer API_CALL mk_buffer_from_char(const char *data, size_t len, on_mk_buffer_free cb, void *user_data) {
return mk_buffer_from_char2(data, len, cb, user_data, nullptr);
}
API_EXPORT mk_buffer API_CALL mk_buffer_from_char2(const char *data, size_t len, on_mk_buffer_free cb, void *user_data, on_user_data_free user_data_free) {
assert(data);
return new Buffer::Ptr(std::make_shared<BufferForC>(data, len, cb, user_data));
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
return new Buffer::Ptr(std::make_shared<BufferForC>(data, len, cb, std::move(ptr)));
}
API_EXPORT mk_buffer API_CALL mk_buffer_ref(mk_buffer buffer) {
@ -201,15 +206,20 @@ void stopAllTcpServer(){
}
API_EXPORT void API_CALL mk_tcp_session_set_user_data(mk_tcp_session session, void *user_data) {
mk_tcp_session_set_user_data2(session, user_data, nullptr);
}
API_EXPORT void API_CALL mk_tcp_session_set_user_data2(mk_tcp_session session, void *user_data, on_user_data_free user_data_free) {
assert(session);
SessionForC *obj = (SessionForC *)session;
obj->_user_data = user_data;
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
obj->_user_data = std::move(ptr);
}
API_EXPORT void* API_CALL mk_tcp_session_get_user_data(mk_tcp_session session){
assert(session);
SessionForC *obj = (SessionForC *)session;
return obj->_user_data;
return obj->_user_data.get();
}
API_EXPORT void API_CALL mk_tcp_server_events_listen(const mk_tcp_session_events *events){
@ -364,13 +374,18 @@ API_EXPORT void API_CALL mk_tcp_client_send_safe(mk_tcp_client ctx, const char *
}
API_EXPORT void API_CALL mk_tcp_client_set_user_data(mk_tcp_client ctx,void *user_data){
mk_tcp_client_set_user_data2(ctx, user_data, nullptr);
}
API_EXPORT void API_CALL mk_tcp_client_set_user_data2(mk_tcp_client ctx, void *user_data, on_user_data_free user_data_free) {
assert(ctx);
TcpClientForC::Ptr *client = (TcpClientForC::Ptr *)ctx;
(*client)->_user_data = user_data;
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
(*client)->_user_data = std::move(ptr);
}
API_EXPORT void* API_CALL mk_tcp_client_get_user_data(mk_tcp_client ctx){
assert(ctx);
TcpClientForC::Ptr *client = (TcpClientForC::Ptr *)ctx;
return (*client)->_user_data;
return (*client)->_user_data.get();
}

View File

@ -25,7 +25,7 @@ public:
void onManager() override;
void onConnect(const toolkit::SockException &ex) override;
void setClient(mk_tcp_client client);
void *_user_data;
std::shared_ptr<void> _user_data;
private:
mk_tcp_client_events _events;
mk_tcp_client _client;
@ -38,7 +38,7 @@ public:
void onRecv(const toolkit::Buffer::Ptr &buffer) override ;
void onError(const toolkit::SockException &err) override;
void onManager() override;
void *_user_data;
std::shared_ptr<void> _user_data;
uint16_t _local_port;
};

View File

@ -44,11 +44,23 @@ API_EXPORT void API_CALL mk_async_do(mk_thread ctx,on_mk_async cb, void *user_da
});
}
API_EXPORT void API_CALL mk_async_do2(mk_thread ctx, on_mk_async cb, void *user_data, on_user_data_free user_data_free){
assert(ctx && cb);
EventPoller *poller = (EventPoller *)ctx;
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
poller->async([cb, ptr]() { cb(ptr.get()); });
}
API_EXPORT void API_CALL mk_async_do_delay(mk_thread ctx, size_t ms, on_mk_async cb, void *user_data) {
mk_async_do_delay2(ctx, ms, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_async_do_delay2(mk_thread ctx, size_t ms, on_mk_async cb, void *user_data, on_user_data_free user_data_free){
assert(ctx && cb && ms);
EventPoller *poller = (EventPoller *)ctx;
poller->doDelayTask(ms, [cb, user_data]() {
cb(user_data);
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
poller->doDelayTask(ms, [cb, ptr]() {
cb(ptr.get());
return 0;
});
}
@ -56,28 +68,26 @@ API_EXPORT void API_CALL mk_async_do_delay(mk_thread ctx, size_t ms, on_mk_async
API_EXPORT void API_CALL mk_sync_do(mk_thread ctx,on_mk_async cb, void *user_data){
assert(ctx && cb);
EventPoller *poller = (EventPoller *)ctx;
poller->sync([cb,user_data](){
cb(user_data);
});
poller->sync([cb, user_data]() { cb(user_data); });
}
class TimerForC : public std::enable_shared_from_this<TimerForC>{
public:
using Ptr = std::shared_ptr<TimerForC>;
TimerForC(on_mk_timer cb, void *user_data){
TimerForC(on_mk_timer cb, std::shared_ptr<void> user_data) {
_cb = cb;
_user_data = user_data;
_user_data = std::move(user_data);
}
~TimerForC(){}
~TimerForC() = default;
uint64_t operator()(){
lock_guard<recursive_mutex> lck(_mxt);
if(!_cb){
return 0;
}
return _cb(_user_data);
return _cb(_user_data.get());
}
void cancel(){
@ -98,15 +108,20 @@ public:
}
private:
on_mk_timer _cb = nullptr;
void *_user_data = nullptr;
std::shared_ptr<void> _user_data;
recursive_mutex _mxt;
EventPoller::DelayTask::Ptr _task;
};
API_EXPORT mk_timer API_CALL mk_timer_create(mk_thread ctx, uint64_t delay_ms, on_mk_timer cb, void *user_data) {
return mk_timer_create2(ctx, delay_ms, cb, user_data, nullptr);
}
API_EXPORT mk_timer API_CALL mk_timer_create2(mk_thread ctx, uint64_t delay_ms, on_mk_timer cb, void *user_data, on_user_data_free user_data_free){
assert(ctx && cb);
EventPoller *poller = (EventPoller *)ctx;
TimerForC::Ptr *ret = new TimerForC::Ptr(new TimerForC(cb, user_data));
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
TimerForC::Ptr *ret = new TimerForC::Ptr(new TimerForC(cb, ptr));
(*ret)->start(delay_ms,*poller);
return ret;
}

View File

@ -114,9 +114,14 @@ API_EXPORT int API_CALL mk_track_bit_rate(mk_track track) {
}
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);
}
API_EXPORT void *API_CALL mk_track_add_delegate2(mk_track track, on_mk_frame_out cb, void *user_data, on_user_data_free user_data_free){
assert(track && cb);
return (*((Track::Ptr *) track))->addDelegate([cb, user_data](const Frame::Ptr &frame) {
cb(user_data, (mk_frame) &frame);
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
return (*((Track::Ptr *) track))->addDelegate([cb, ptr](const Frame::Ptr &frame) {
cb(ptr.get(), (mk_frame) &frame);
return true;
});
}

View File

@ -57,9 +57,14 @@ API_EXPORT void API_CALL mk_decoder_set_max_async_frame_size(mk_decoder ctx, siz
}
API_EXPORT void API_CALL mk_decoder_set_cb(mk_decoder ctx, on_mk_decode cb, void *user_data) {
mk_decoder_set_cb2(ctx, cb, user_data, nullptr);
}
API_EXPORT void API_CALL mk_decoder_set_cb2(mk_decoder ctx, on_mk_decode cb, void *user_data, on_user_data_free user_data_free){
assert(ctx && cb);
((FFmpegDecoder *) ctx)->setOnDecode([cb, user_data](const FFmpegFrame::Ptr &pix_frame) {
cb(user_data, (mk_frame_pix) &pix_frame);
std::shared_ptr<void> ptr(user_data, user_data_free ? user_data_free : [](void *) {});
((FFmpegDecoder *) ctx)->setOnDecode([cb, ptr](const FFmpegFrame::Ptr &pix_frame) {
cb(ptr.get(), (mk_frame_pix) &pix_frame);
});
}