全面更新整理c sdk

This commit is contained in:
ziyue
2022-05-25 15:38:32 +08:00
parent 9736badcea
commit cb0e5c6c57
29 changed files with 1543 additions and 416 deletions

View File

@@ -14,6 +14,7 @@
#include "Util/logger.h"
#include "Util/SSLBox.h"
#include "Network/TcpServer.h"
#include "Network/UdpServer.h"
#include "Thread/WorkThreadPool.h"
#include "Rtsp/RtspSession.h"

176
api/source/mk_frame.cpp Normal file
View File

@@ -0,0 +1,176 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "mk_frame.h"
#include "Extension/Frame.h"
#include "Extension/H264.h"
#include "Extension/H265.h"
#include "Extension/AAC.h"
using namespace mediakit;
extern "C" {
#define XX(name, type, value, str, mpeg_id) const int MK##name = value;
CODEC_MAP(XX)
#undef XX
}
class FrameFromPtrForC : public FrameFromPtr {
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(
std::forward<ARGS>(args)...) {
_flags = flags;
_cb = cb;
_user_data = user_data;
_cache_able = cache_able;
}
~FrameFromPtrForC() override {
if (_cb) {
_cb(_user_data, _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);
}
private:
uint32_t _flags;
on_mk_frame_data_release _cb;
void *_user_data;
bool _cache_able;
};
static mk_frame mk_frame_create_complex(int codec_id, uint32_t dts, uint32_t pts, uint32_t frame_flags, size_t prefix_size,
char *data, size_t size, on_mk_frame_data_release cb, 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));
case CodecH265:
return new Frame::Ptr(new H265FrameHelper<FrameFromPtrForC>(cb, frame_flags, cb, 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));
}
}
API_EXPORT mk_frame API_CALL mk_frame_create(int codec_id, uint32_t dts, uint32_t pts, const char *data, size_t size,
on_mk_frame_data_release cb, void *user_data) {
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);
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);
}
default:
return mk_frame_create_complex(codec_id, dts, pts, 0, 0, (char *)data, size, cb, user_data);
}
}
API_EXPORT void API_CALL mk_frame_unref(mk_frame frame) {
assert(frame);
delete (Frame::Ptr *) frame;
}
API_EXPORT mk_frame API_CALL mk_frame_ref(mk_frame frame) {
assert(frame);
return new Frame::Ptr(Frame::getCacheAbleFrame(*((Frame::Ptr *) frame)));
}
API_EXPORT int API_CALL mk_frame_codec_id(mk_frame frame) {
assert(frame);
return (*((Frame::Ptr *) frame))->getCodecId();
}
API_EXPORT const char *API_CALL mk_frame_codec_name(mk_frame frame) {
assert(frame);
return (*((Frame::Ptr *) frame))->getCodecName();
}
API_EXPORT int API_CALL mk_frame_is_video(mk_frame frame) {
assert(frame);
return (*((Frame::Ptr *) frame))->getTrackType() == TrackVideo;
}
API_EXPORT const char *API_CALL mk_frame_get_data(mk_frame frame) {
assert(frame);
return (*((Frame::Ptr *) frame))->data();
}
API_EXPORT size_t API_CALL mk_frame_get_data_size(mk_frame frame) {
assert(frame);
return (*((Frame::Ptr *) frame))->size();
}
API_EXPORT size_t API_CALL mk_frame_get_data_prefix_size(mk_frame frame) {
assert(frame);
return (*((Frame::Ptr *) frame))->prefixSize();
}
API_EXPORT uint32_t API_CALL mk_frame_get_dts(mk_frame frame) {
assert(frame);
return (*((Frame::Ptr *) frame))->dts();
}
API_EXPORT uint32_t API_CALL mk_frame_get_pts(mk_frame frame) {
assert(frame);
return (*((Frame::Ptr *) frame))->pts();
}
API_EXPORT uint32_t API_CALL mk_frame_get_flags(mk_frame frame) {
assert(frame);
auto &ref = *((Frame::Ptr *) frame);
uint32_t ret = 0;
if (ref->keyFrame()) {
ret &= MK_FRAME_FLAG_IS_KEY;
}
if (ref->configFrame()) {
ret &= MK_FRAME_FLAG_IS_CONFIG;
}
if (ref->dropAble()) {
ret &= MK_FRAME_FLAG_DROP_ABLE;
}
if (!ref->decodeAble()) {
ret &= MK_FRAME_FLAG_NOT_DECODE_ABLE;
}
return ret;
}

View File

@@ -178,7 +178,7 @@ API_EXPORT void API_CALL mk_media_release(mk_media ctx) {
delete obj;
}
API_EXPORT int API_CALL mk_media_init_video(mk_media ctx, int codec_id, int width, int height, float fps){
API_EXPORT int API_CALL mk_media_init_video(mk_media ctx, int codec_id, int width, int height, float fps, int bit_rate){
assert(ctx);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
VideoInfo info;
@@ -186,6 +186,8 @@ API_EXPORT int API_CALL mk_media_init_video(mk_media ctx, int codec_id, int widt
info.iFrameRate = fps;
info.iWidth = width;
info.iHeight = height;
info.iBitRate = bit_rate;
(*obj)->getChannel()->initVideo(info);
return (*obj)->getChannel()->initVideo(info);
}
@@ -200,12 +202,24 @@ API_EXPORT int API_CALL mk_media_init_audio(mk_media ctx, int codec_id, int samp
return (*obj)->getChannel()->initAudio(info);
}
API_EXPORT void API_CALL mk_media_init_track(mk_media ctx, mk_track track){
assert(ctx && track);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->getChannel()->addTrack(*((Track::Ptr *) track));
}
API_EXPORT void API_CALL mk_media_init_complete(mk_media ctx){
assert(ctx);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->getChannel()->addTrackCompleted();
}
API_EXPORT int API_CALL mk_media_input_frame(mk_media ctx, mk_frame frame){
assert(ctx && frame);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
return (*obj)->getChannel()->inputFrame(*((Frame::Ptr *) frame));
}
API_EXPORT int API_CALL mk_media_input_h264(mk_media ctx, const void *data, int len, uint32_t dts, uint32_t pts) {
assert(ctx && data && len > 0);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
@@ -218,6 +232,12 @@ API_EXPORT int API_CALL mk_media_input_h265(mk_media ctx, const void *data, int
return (*obj)->getChannel()->inputH265((const char *) data, len, dts, pts);
}
API_EXPORT void API_CALL mk_media_input_yuv(mk_media ctx, const char *yuv[3], int linesize[3], uint32_t cts) {
assert(ctx && yuv && linesize);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;
(*obj)->getChannel()->inputYUV((char **) yuv, linesize, cts);
}
API_EXPORT int API_CALL mk_media_input_aac(mk_media ctx, const void *data, int len, uint32_t dts, void *adts) {
assert(ctx && data && len > 0 && adts);
MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx;

View File

@@ -47,51 +47,34 @@ public:
});
}
void unset(){
void unset() {
for (auto &track : _player->getTracks(false)) {
track->clear();
}
lock_guard<recursive_mutex> lck(_mtx);
_on_play = nullptr;
_on_shutdown = nullptr;
_on_data = nullptr;
}
void onEvent(bool is_shutdown, const SockException &ex){
lock_guard<recursive_mutex> lck(_mtx);
if(is_shutdown){
if (is_shutdown) {
//播放中断
if(_on_shutdown){
_on_shutdown(_on_shutdown_data,ex.getErrCode(),ex.what());
if (_on_shutdown) {
_on_shutdown(_on_shutdown_data, ex.getErrCode(), ex.what(), nullptr, 0);
}
return;
}
//播放结果
if(_on_play){
_on_play(_on_play_data,ex.getErrCode(),ex.what());
}
if(ex){
//播放失败
return;
}
//播放成功,添加事件回调
weak_ptr<MediaPlayerForC> weak_self = shared_from_this();
auto delegate = std::make_shared<FrameWriterInterfaceHelper>([weak_self](const Frame::Ptr &frame) {
if (auto strong_self = weak_self.lock()) {
strong_self->onData(frame);
return true;
if (_on_play) {
auto cpp_tracks = _player->getTracks(false);
mk_track tracks[TrackMax] = {nullptr};
int track_count = 0;
for (auto &track : cpp_tracks) {
tracks[track_count++] = (mk_track) &track;
}
return false;
});
for (auto &track : _player->getTracks(false)) {
track->addDelegate(delegate);
}
}
void onData(const Frame::Ptr &frame){
lock_guard<recursive_mutex> lck(_mtx);
if(_on_data){
_on_data(_on_data_data,frame->getTrackType(),frame->getCodecId(),frame->data(),frame->size(),frame->dts(),frame->pts());
_on_play(_on_play_data, ex.getErrCode(), ex.what(), tracks, track_count);
}
}
@@ -106,12 +89,6 @@ public:
}
}
void setOnData(on_mk_play_data cb, void *user_data) {
lock_guard<recursive_mutex> lck(_mtx);
_on_data_data = user_data;
_on_data = cb;
}
MediaPlayer::Ptr& getPlayer(){
return _player;
}
@@ -119,12 +96,10 @@ private:
MediaPlayer::Ptr _player;
recursive_mutex _mtx;
on_mk_play_event _on_play = nullptr;
on_mk_play_data _on_data = nullptr;
on_mk_play_event _on_shutdown = nullptr;
void *_on_play_data = nullptr;
void *_on_shutdown_data = nullptr;
void *_on_data_data = nullptr;
};
API_EXPORT mk_player API_CALL mk_player_create() {
@@ -214,90 +189,6 @@ API_EXPORT void API_CALL mk_player_set_on_shutdown(mk_player ctx, on_mk_play_eve
mk_player_set_on_event(ctx,cb,user_data,1);
}
API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb, void *user_data) {
assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
obj.setOnData(cb,user_data);
}
API_EXPORT int API_CALL mk_player_video_codec_id(mk_player ctx){
assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo));
return track ? track->getCodecId() : CodecInvalid;
}
API_EXPORT int API_CALL mk_player_video_codec_id_vendor_head(mk_player ctx, char *vendor, char *head, int *head_len) {
assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *) ctx);
auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo));
int codecId = track ? track->getCodecId() : CodecInvalid;
if (codecId == CodecH264) {
auto h264Track = dynamic_pointer_cast<H264Track>(obj->getTrack(TrackVideo));
auto pps = h264Track->getPps();
auto ppsLen = pps.size();
if (ppsLen >= (4 + 16)) {
std::string temVendor = std::string(pps.c_str() + 4, 16);
memcpy(vendor, temVendor.c_str(), temVendor.length());
if (ppsLen > (4 + 16)) {
std::string temHead = std::string(pps.c_str() + 20, ppsLen - 20);
memcpy(head, temHead.c_str(), temHead.length());
*head_len = temHead.length();
}
}
}
return codecId;
}
API_EXPORT int API_CALL mk_player_video_width(mk_player ctx) {
assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo));
return track ? track->getVideoWidth() : 0;
}
API_EXPORT int API_CALL mk_player_video_height(mk_player ctx) {
assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo));
return track ? track->getVideoHeight() : 0;
}
API_EXPORT float API_CALL mk_player_video_fps(mk_player ctx) {
assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
auto track = dynamic_pointer_cast<VideoTrack>(obj->getTrack(TrackVideo));
return track ? track->getVideoFps() : 0;
}
API_EXPORT int API_CALL mk_player_audio_codec_id(mk_player ctx){
assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
auto track = dynamic_pointer_cast<AudioTrack>(obj->getTrack(TrackAudio));
return track ? track->getCodecId() : CodecInvalid;
}
API_EXPORT int API_CALL mk_player_audio_samplerate(mk_player ctx) {
assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
auto track = dynamic_pointer_cast<AudioTrack>(obj->getTrack(TrackAudio));
return track ? track->getAudioSampleRate() : 0;
}
API_EXPORT int API_CALL mk_player_audio_bit(mk_player ctx) {
assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
auto track = dynamic_pointer_cast<AudioTrack>(obj->getTrack(TrackAudio));
return track ? track->getAudioSampleBit() : 0;
}
API_EXPORT int API_CALL mk_player_audio_channel(mk_player ctx) {
assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);
auto track = dynamic_pointer_cast<AudioTrack>(obj->getTrack(TrackAudio));
return track ? track->getAudioChannel() : 0;
}
API_EXPORT float API_CALL mk_player_duration(mk_player ctx) {
assert(ctx);
MediaPlayerForC &obj = **((MediaPlayerForC::Ptr *)ctx);

View File

@@ -13,10 +13,76 @@
#include "mk_tcp_private.h"
#include "Http/WebSocketClient.h"
#include "Http/WebSocketSession.h"
#include "Network/Buffer.h"
using namespace toolkit;
using namespace mediakit;
class BufferForC : public Buffer {
public:
BufferForC(const char *data, size_t len, on_mk_buffer_free cb, void *user_data) {
if (len <= 0) {
len = strlen(data);
}
if (!cb) {
auto ptr = malloc(len);
memcpy(ptr, data, len);
data = (char *) ptr;
cb = [](void *user_data, void *data) {
free(data);
};
}
_data = (char *) data;
_size = len;
_cb = cb;
_user_data = user_data;
}
~BufferForC() override {
_cb(_user_data, _data);
}
char *data() const override {
return _data;
}
size_t size() const override {
return _size;
}
private:
char *_data;
size_t _size;
on_mk_buffer_free _cb;
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) {
assert(data);
return new Buffer::Ptr(std::make_shared<BufferForC>(data, len, cb, user_data));
}
API_EXPORT mk_buffer API_CALL mk_buffer_ref(mk_buffer buffer) {
assert(buffer);
return new Buffer::Ptr(*((Buffer::Ptr *) buffer));
}
API_EXPORT void API_CALL mk_buffer_unref(mk_buffer buffer) {
assert(buffer);
delete (Buffer::Ptr *) buffer;
}
API_EXPORT const char *API_CALL mk_buffer_get_data(mk_buffer buffer) {
assert(buffer);
return (*((Buffer::Ptr *) buffer))->data();
}
API_EXPORT size_t API_CALL mk_buffer_get_size(mk_buffer buffer) {
assert(buffer);
return (*((Buffer::Ptr *) buffer))->size();
}
API_EXPORT const char* API_CALL mk_sock_info_peer_ip(const mk_sock_info ctx, char *buf){
assert(ctx);
SockInfo *sock = (SockInfo *)ctx;
@@ -53,34 +119,54 @@ API_EXPORT void API_CALL mk_tcp_session_shutdown(const mk_tcp_session ctx,int er
session->safeShutdown(SockException((ErrCode)err,err_msg));
}
API_EXPORT void API_CALL mk_tcp_session_send(const mk_tcp_session ctx,const char *data, size_t len){
assert(ctx && data);
if(!len){
len = strlen(data);
}
TcpSessionForC *session = (TcpSessionForC *)ctx;
session->SockSender::send(data,len);
API_EXPORT void API_CALL mk_tcp_session_send_buffer(const mk_tcp_session ctx, mk_buffer buffer) {
assert(ctx && buffer);
TcpSessionForC *session = (TcpSessionForC *) ctx;
session->send(*((Buffer::Ptr *) buffer));
}
API_EXPORT void API_CALL mk_tcp_session_send_safe(const mk_tcp_session ctx,const char *data,size_t len){
assert(ctx && data);
if (!len) {
len = strlen(data);
}
API_EXPORT void API_CALL mk_tcp_session_send(const mk_tcp_session ctx, const char *data, size_t len) {
auto buffer = mk_buffer_from_char(data, len, nullptr, nullptr);
mk_tcp_session_send_buffer(ctx, buffer);
mk_buffer_unref(buffer);
}
API_EXPORT void API_CALL mk_tcp_session_send_buffer_safe(const mk_tcp_session ctx, mk_buffer buffer) {
assert(ctx && buffer);
try {
std::weak_ptr<TcpSession> weak_session = ((TcpSessionForC *)ctx)->shared_from_this();
std::string str = std::string(data,len);
((TcpSessionForC *)ctx)->async([weak_session,str](){
std::weak_ptr<TcpSession> weak_session = ((TcpSessionForC *) ctx)->shared_from_this();
auto ref = mk_buffer_ref(buffer);
((TcpSessionForC *) ctx)->async([weak_session, ref]() {
auto session_session = weak_session.lock();
if(session_session){
session_session->SockSender::send(str);
if (session_session) {
session_session->send(*((Buffer::Ptr *) ref));
}
mk_buffer_unref(ref);
});
} catch (std::exception &ex) {
WarnL << "can not got the strong pionter of this mk_tcp_session:" << ex.what();
}
}
API_EXPORT mk_tcp_session_ref API_CALL mk_tcp_session_ref_from(const mk_tcp_session ctx) {
auto ref = ((TcpSessionForC *) ctx)->shared_from_this();
return new std::shared_ptr<TcpSessionForC>(std::dynamic_pointer_cast<TcpSessionForC>(ref));
}
API_EXPORT void mk_tcp_session_ref_release(const mk_tcp_session_ref ref) {
delete (std::shared_ptr<TcpSessionForC> *) ref;
}
API_EXPORT mk_tcp_session mk_tcp_session_from_ref(const mk_tcp_session_ref ref) {
return ((std::shared_ptr<TcpSessionForC> *) ref)->get();
}
API_EXPORT void API_CALL mk_tcp_session_send_safe(const mk_tcp_session ctx, const char *data, size_t len) {
auto buffer = mk_buffer_from_char(data, len, nullptr, nullptr);
mk_tcp_session_send_buffer_safe(ctx, buffer);
mk_buffer_unref(buffer);
}
////////////////////////////////////////TcpSessionForC////////////////////////////////////////////////
static TcpServer::Ptr s_tcp_server[4];
static mk_tcp_session_events s_events_server = {0};
@@ -94,7 +180,7 @@ TcpSessionForC::TcpSessionForC(const Socket::Ptr &pSock) : TcpSession(pSock) {
void TcpSessionForC::onRecv(const Buffer::Ptr &buffer) {
if (s_events_server.on_mk_tcp_session_data) {
s_events_server.on_mk_tcp_session_data(_local_port,this, buffer->data(), buffer->size());
s_events_server.on_mk_tcp_session_data(_local_port, this, (mk_buffer)&buffer);
}
}
@@ -169,10 +255,9 @@ TcpClientForC::TcpClientForC(mk_tcp_client_events *events){
_events = *events;
}
void TcpClientForC::onRecv(const Buffer::Ptr &pBuf) {
if(_events.on_mk_tcp_client_data){
_events.on_mk_tcp_client_data(_client,pBuf->data(),pBuf->size());
if (_events.on_mk_tcp_client_data) {
_events.on_mk_tcp_client_data(_client, (mk_buffer)&pBuf);
}
}
@@ -246,24 +331,36 @@ API_EXPORT void API_CALL mk_tcp_client_connect(mk_tcp_client ctx, const char *ho
(*client)->startConnect(host,port);
}
API_EXPORT void API_CALL mk_tcp_client_send(mk_tcp_client ctx, const char *data, int len){
assert(ctx && data);
TcpClientForC::Ptr *client = (TcpClientForC::Ptr *)ctx;
(*client)->SockSender::send(data,len);
API_EXPORT void API_CALL mk_tcp_client_send_buffer(mk_tcp_client ctx, mk_buffer buffer) {
assert(ctx && buffer);
TcpClientForC::Ptr *client = (TcpClientForC::Ptr *) ctx;
(*client)->send(*((Buffer::Ptr *) buffer));
}
API_EXPORT void API_CALL mk_tcp_client_send(mk_tcp_client ctx, const char *data, int len) {
auto buffer = mk_buffer_from_char(data, len, nullptr, nullptr);
mk_tcp_client_send_buffer(ctx, buffer);
mk_buffer_unref(buffer);
}
API_EXPORT void API_CALL mk_tcp_client_send_buffer_safe(mk_tcp_client ctx, mk_buffer buffer) {
assert(ctx && buffer);
TcpClientForC::Ptr *client = (TcpClientForC::Ptr *) ctx;
std::weak_ptr<TcpClient> weakClient = *client;
auto ref = mk_buffer_ref(buffer);
(*client)->async([weakClient, ref]() {
auto strongClient = weakClient.lock();
if (strongClient) {
strongClient->send(*((Buffer::Ptr *) ref));
}
mk_buffer_unref(ref);
});
}
API_EXPORT void API_CALL mk_tcp_client_send_safe(mk_tcp_client ctx, const char *data, int len){
assert(ctx && data);
TcpClientForC::Ptr *client = (TcpClientForC::Ptr *)ctx;
std::weak_ptr<TcpClient> weakClient = *client;
auto buf = BufferRaw::create();
buf->assign(data,len);
(*client)->async([weakClient,buf](){
auto strongClient = weakClient.lock();
if(strongClient){
strongClient->send(buf);
}
});
auto buffer = mk_buffer_from_char(data, len, nullptr, nullptr);
mk_tcp_client_send_buffer_safe(ctx, buffer);
mk_buffer_unref(buffer);
}
API_EXPORT void API_CALL mk_tcp_client_set_user_data(mk_tcp_client ctx,void *user_data){

View File

@@ -44,6 +44,15 @@ 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_do_delay(mk_thread ctx, size_t ms, on_mk_async cb, void *user_data) {
assert(ctx && cb && ms);
EventPoller *poller = (EventPoller *) ctx;
poller->doDelayTask(ms, [cb, user_data]() {
cb(user_data);
return 0;
});
}
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;
@@ -107,4 +116,52 @@ API_EXPORT void API_CALL mk_timer_release(mk_timer ctx){
TimerForC::Ptr *obj = (TimerForC::Ptr *)ctx;
(*obj)->cancel();
delete obj;
}
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);
}
EventPoller::Ptr getPoller() {
return dynamic_pointer_cast<EventPoller>(getExecutor());
}
};
API_EXPORT mk_thread_pool API_CALL mk_thread_pool_create(const char *name, size_t n_thread, int priority) {
return new WorkThreadPoolForC(name, n_thread, priority);
}
API_EXPORT int API_CALL mk_thread_pool_release(mk_thread_pool pool) {
assert(pool);
delete (WorkThreadPoolForC *) pool;
return 0;
}
API_EXPORT mk_thread API_CALL mk_thread_from_thread_pool(mk_thread_pool pool) {
assert(pool);
return ((WorkThreadPoolForC *) pool)->getPoller().get();
}
API_EXPORT mk_sem API_CALL mk_sem_create() {
return new toolkit::semaphore;
}
API_EXPORT void API_CALL mk_sem_release(mk_sem sem) {
assert(sem);
delete (toolkit::semaphore *) sem;
}
API_EXPORT void API_CALL mk_sem_post(mk_sem sem, size_t n) {
assert(sem);
((toolkit::semaphore *) sem)->post(n);
}
API_EXPORT void API_CALL mk_sem_wait(mk_sem sem) {
assert(sem);
((toolkit::semaphore *) sem)->wait();
}

196
api/source/mk_track.cpp Normal file
View File

@@ -0,0 +1,196 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "mk_track.h"
#include "Extension/Track.h"
using namespace std;
using namespace toolkit;
using namespace mediakit;
class VideoTrackForC : public VideoTrack {
public:
VideoTrackForC(int codec_id, codec_args *args) {
_codec_id = (CodecId) codec_id;
if (args) {
_args = *args;
} else {
memset(&_args, 0, sizeof(_args));
}
}
~VideoTrackForC() override = default;
int getVideoHeight() const override {
return _args.video.height;
}
int getVideoWidth() const override {
return _args.video.width;
}
float getVideoFps() const override {
return _args.video.fps;
}
CodecId getCodecId() const override {
return _codec_id;
}
bool ready() override {
return true;
}
Track::Ptr clone() override {
return std::make_shared<std::remove_reference<decltype(*this)>::type>(*this);
}
Sdp::Ptr getSdp() override {
return nullptr;
}
private:
CodecId _codec_id;
codec_args _args;
};
class AudioTrackForC : public AudioTrackImp {
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 {
return std::make_shared<std::remove_reference<decltype(*this)>::type>(*this);
}
Sdp::Ptr getSdp() override {
return nullptr;
}
};
API_EXPORT mk_track API_CALL mk_track_create(int codec_id, codec_args *args) {
switch (getTrackType((CodecId) codec_id)) {
case TrackVideo: return new Track::Ptr(std::make_shared<VideoTrackForC>(codec_id, args));
case TrackAudio: return new Track::Ptr(std::make_shared<AudioTrackForC>(codec_id, args));
default: WarnL << "unrecognized codec:" << codec_id; return nullptr;
}
}
API_EXPORT void API_CALL mk_track_unref(mk_track track) {
assert(track);
delete (Track::Ptr *)track;
}
API_EXPORT mk_track API_CALL mk_track_ref(mk_track track) {
assert(track);
return new Track::Ptr(*( (Track::Ptr *)track));
}
API_EXPORT int API_CALL mk_track_codec_id(mk_track track) {
assert(track);
return (*((Track::Ptr *) track))->getCodecId();
}
API_EXPORT const char *API_CALL mk_track_codec_name(mk_track track) {
assert(track);
return (*((Track::Ptr *) track))->getCodecName();
}
API_EXPORT int API_CALL mk_track_bit_rate(mk_track track) {
assert(track);
return (*((Track::Ptr *) track))->getBitRate();
}
API_EXPORT void *API_CALL mk_track_add_delegate(mk_track track, on_mk_frame_out cb, void *user_data) {
assert(track && cb);
auto delegate = std::make_shared<FrameWriterInterfaceHelper>([cb, user_data](const Frame::Ptr &frame) {
cb(user_data, (mk_frame) &frame);
return true;
});
(*((Track::Ptr *) track))->addDelegate(delegate);
return delegate.get();
}
API_EXPORT void API_CALL mk_track_del_delegate(mk_track track, void *tag) {
assert(track && tag);
(*((Track::Ptr *) track))->delDelegate((FrameWriterInterface *) tag);
}
API_EXPORT void API_CALL mk_track_input_frame(mk_track track, mk_frame frame) {
assert(track && frame);
(*((Track::Ptr *) track))->inputFrame((*((Frame::Ptr *) frame)));
}
API_EXPORT int API_CALL mk_track_is_video(mk_track track) {
assert(track);
return (*((Track::Ptr *) track))->getTrackType() == TrackVideo;
}
API_EXPORT int API_CALL mk_track_video_width(mk_track track) {
assert(track);
auto video = dynamic_pointer_cast<VideoTrack>((*((Track::Ptr *) track)));
if (video) {
return video->getVideoWidth();
}
WarnL << "not video track";
return 0;
}
API_EXPORT int API_CALL mk_track_video_height(mk_track track) {
assert(track);
auto video = dynamic_pointer_cast<VideoTrack>((*((Track::Ptr *) track)));
if (video) {
return video->getVideoHeight();
}
WarnL << "not video track";
return 0;
}
API_EXPORT int API_CALL mk_track_video_fps(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_audio_sample_rate(mk_track track) {
assert(track);
auto audio = dynamic_pointer_cast<AudioTrack>((*((Track::Ptr *) track)));
if (audio) {
return audio->getAudioSampleRate();
}
WarnL << "not audio track";
return 0;
}
API_EXPORT int API_CALL mk_track_audio_channel(mk_track track) {
assert(track);
auto audio = dynamic_pointer_cast<AudioTrack>((*((Track::Ptr *) track)));
if (audio) {
return audio->getAudioChannel();
}
WarnL << "not audio track";
return 0;
}
API_EXPORT int API_CALL mk_track_audio_sample_bit(mk_track track) {
assert(track);
auto audio = dynamic_pointer_cast<AudioTrack>((*((Track::Ptr *) track)));
if (audio) {
return audio->getAudioSampleBit();
}
WarnL << "not audio track";
return 0;
}

126
api/source/mk_transcode.cpp Normal file
View File

@@ -0,0 +1,126 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include "mk_transcode.h"
#include "Extension/Track.h"
using namespace mediakit;
#ifdef ENABLE_FFMPEG
#include "Codec/Transcode.h"
API_EXPORT mk_decoder API_CALL mk_decoder_create(mk_track track, int thread_num) {
assert(track);
return new FFmpegDecoder(*((Track::Ptr *)track), thread_num);
}
API_EXPORT void API_CALL mk_decoder_release(mk_decoder ctx, int flush_frame) {
assert(ctx);
auto decoder = (FFmpegDecoder *)ctx;
if (flush_frame) {
decoder->stopThread(false);
}
delete decoder;
}
API_EXPORT void API_CALL mk_decoder_decode(mk_decoder ctx, mk_frame frame, int async, int enable_merge) {
assert(ctx && frame);
((FFmpegDecoder *)ctx)->inputFrame(*((Frame::Ptr *)frame), false, async, enable_merge);
}
API_EXPORT void API_CALL mk_decoder_set_max_async_frame_size(mk_decoder ctx, size_t size) {
assert(ctx && size);
((FFmpegDecoder *)ctx)->setMaxTaskSize(size);
}
API_EXPORT void API_CALL mk_decoder_set_cb(mk_decoder ctx, on_mk_decode cb, void *user_data) {
assert(ctx && cb);
((FFmpegDecoder *)ctx)->setOnDecode([cb, user_data](const FFmpegFrame::Ptr &pix_frame) {
cb(user_data, (mk_frame_pix)&pix_frame);
});
}
API_EXPORT const AVCodecContext *API_CALL mk_decoder_get_context(mk_decoder ctx) {
assert(ctx);
return ((FFmpegDecoder *)ctx)->getContext();
}
/////////////////////////////////////////////////////////////////////////////////////////////
API_EXPORT mk_frame_pix API_CALL mk_frame_pix_ref(mk_frame_pix frame) {
assert(frame);
return new FFmpegFrame::Ptr(*(FFmpegFrame::Ptr *)frame);
}
API_EXPORT mk_frame_pix API_CALL mk_frame_pix_from_av_frame(AVFrame *frame) {
assert(frame);
return new FFmpegFrame::Ptr(std::make_shared<FFmpegFrame>(
std::shared_ptr<AVFrame>(av_frame_clone(frame), [](AVFrame *frame) { av_frame_free(&frame); })));
}
API_EXPORT void API_CALL mk_frame_pix_unref(mk_frame_pix frame) {
assert(frame);
delete (FFmpegFrame::Ptr *)frame;
}
API_EXPORT AVFrame *API_CALL mk_frame_pix_get_av_frame(mk_frame_pix frame) {
assert(frame);
return (*(FFmpegFrame::Ptr *)frame)->get();
}
//////////////////////////////////////////////////////////////////////////////////
API_EXPORT mk_swscale mk_swscale_create(int output, int width, int height) {
return new FFmpegSws((AVPixelFormat)output, width, height);
}
API_EXPORT void mk_swscale_release(mk_swscale ctx) {
delete (FFmpegSws *)ctx;
}
API_EXPORT int mk_swscale_input_frame(mk_swscale ctx, mk_frame_pix frame, uint8_t *data) {
return ((FFmpegSws *)ctx)->inputFrame(*(FFmpegFrame::Ptr *)frame, data);
}
API_EXPORT mk_frame_pix mk_swscale_input_frame2(mk_swscale ctx, mk_frame_pix frame) {
return new FFmpegFrame::Ptr(((FFmpegSws *)ctx)->inputFrame(*(FFmpegFrame::Ptr *)frame));
}
API_EXPORT uint8_t **API_CALL mk_get_av_frame_data(AVFrame *frame) {
return frame->data;
}
API_EXPORT int *API_CALL mk_get_av_frame_line_size(AVFrame *frame) {
return frame->linesize;
}
API_EXPORT int64_t API_CALL mk_get_av_frame_dts(AVFrame *frame) {
return frame->pkt_dts;
}
API_EXPORT int64_t API_CALL mk_get_av_frame_pts(AVFrame *frame) {
return frame->pts;
}
API_EXPORT int API_CALL mk_get_av_frame_width(AVFrame *frame) {
return frame->width;
}
API_EXPORT int API_CALL mk_get_av_frame_height(AVFrame *frame) {
return frame->height;
}
API_EXPORT int API_CALL mk_get_av_frame_format(AVFrame *frame) {
return frame->format;
}
#endif //ENABLE_FFMPEG