mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-30 14:52:23 +08:00
完善mk_transcode相关接口
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "mk_common.h"
|
||||
#include "mk_track.h"
|
||||
#include "mk_tcp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -39,6 +40,16 @@ typedef void(API_CALL *on_mk_decode)(void *user_data, mk_frame_pix frame);
|
||||
*/
|
||||
API_EXPORT mk_decoder API_CALL mk_decoder_create(mk_track track, int thread_num);
|
||||
|
||||
/**
|
||||
* 创建解码器
|
||||
* @param track track对象
|
||||
* @param thread_num 解码线程数,0时为自动
|
||||
* @param codec_name_list 偏好的ffmpeg codec name列表,以NULL结尾,譬如:{"libopenh264", "h264_nvdec", NULL};
|
||||
* 在数组中越前,优先级越高;如果指定的codec不存在,或跟mk_track_codec_id类型不匹配时,则使用内部默认codec列表
|
||||
* @return 返回解码器对象,NULL代表失败
|
||||
*/
|
||||
API_EXPORT mk_decoder API_CALL mk_decoder_create2(mk_track track, int thread_num, const char *codec_name_list[]);
|
||||
|
||||
/**
|
||||
* 销毁解码器
|
||||
* @param ctx 解码器对象
|
||||
@@ -96,6 +107,15 @@ API_EXPORT void API_CALL mk_frame_pix_unref(mk_frame_pix frame);
|
||||
*/
|
||||
API_EXPORT mk_frame_pix API_CALL mk_frame_pix_from_av_frame(AVFrame *frame);
|
||||
|
||||
/**
|
||||
* 可无内存拷贝的创建mk_frame_pix对象
|
||||
* @param plane_data 多个平面数据, 通过mk_buffer_get_data获取其数据指针
|
||||
* @param line_size 平面数据line size
|
||||
* @param plane 数据平面个数
|
||||
* @return mk_frame_pix对象
|
||||
*/
|
||||
API_EXPORT mk_frame_pix API_CALL mk_frame_pix_from_buffer(mk_buffer plane_data[], int line_size[], int plane);
|
||||
|
||||
/**
|
||||
* 获取FFmpeg AVFrame对象
|
||||
* @param frame 解码帧mk_frame_pix
|
||||
@@ -139,13 +159,26 @@ API_EXPORT mk_frame_pix mk_swscale_input_frame2(mk_swscale ctx, mk_frame_pix fra
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
API_EXPORT uint8_t** API_CALL mk_get_av_frame_data(AVFrame *frame);
|
||||
API_EXPORT int* API_CALL mk_get_av_frame_line_size(AVFrame *frame);
|
||||
API_EXPORT uint8_t **API_CALL mk_get_av_frame_data(AVFrame *frame);
|
||||
API_EXPORT void API_CALL mk_set_av_frame_data(AVFrame *frame, uint8_t *data, int plane);
|
||||
|
||||
API_EXPORT int *API_CALL mk_get_av_frame_line_size(AVFrame *frame);
|
||||
API_EXPORT void API_CALL mk_set_av_frame_line_size(AVFrame *frame, int line_size, int plane);
|
||||
|
||||
API_EXPORT int64_t API_CALL mk_get_av_frame_dts(AVFrame *frame);
|
||||
API_EXPORT void API_CALL mk_set_av_frame_dts(AVFrame *frame, int64_t dts);
|
||||
|
||||
API_EXPORT int64_t API_CALL mk_get_av_frame_pts(AVFrame *frame);
|
||||
API_EXPORT void API_CALL mk_set_av_frame_pts(AVFrame *frame, int64_t pts);
|
||||
|
||||
API_EXPORT int API_CALL mk_get_av_frame_width(AVFrame *frame);
|
||||
API_EXPORT void API_CALL mk_set_av_frame_width(AVFrame *frame, int width);
|
||||
|
||||
API_EXPORT int API_CALL mk_get_av_frame_height(AVFrame *frame);
|
||||
API_EXPORT void API_CALL mk_set_av_frame_height(AVFrame *frame, int height);
|
||||
|
||||
API_EXPORT int API_CALL mk_get_av_frame_format(AVFrame *frame);
|
||||
API_EXPORT void API_CALL mk_set_av_frame_format(AVFrame *frame, int format);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -13,18 +13,33 @@
|
||||
|
||||
using namespace mediakit;
|
||||
|
||||
std::vector<std::string> toCodecList(const char *codec_name_list[]) {
|
||||
std::vector<std::string> codec_list;
|
||||
auto i = 0U;
|
||||
while (codec_name_list[i]) {
|
||||
codec_list.emplace_back(codec_name_list[i]);
|
||||
++i;
|
||||
}
|
||||
return codec_list;
|
||||
}
|
||||
|
||||
#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);
|
||||
return new FFmpegDecoder(*((Track::Ptr *) track), thread_num);
|
||||
}
|
||||
|
||||
API_EXPORT mk_decoder API_CALL mk_decoder_create2(mk_track track, int thread_num, const char *codec_name_list[]) {
|
||||
assert(track && codec_name_list);
|
||||
return new FFmpegDecoder(*((Track::Ptr *) track), thread_num, toCodecList(codec_name_list));
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_decoder_release(mk_decoder ctx, int flush_frame) {
|
||||
assert(ctx);
|
||||
auto decoder = (FFmpegDecoder *)ctx;
|
||||
auto decoder = (FFmpegDecoder *) ctx;
|
||||
if (flush_frame) {
|
||||
decoder->stopThread(false);
|
||||
}
|
||||
@@ -33,94 +48,142 @@ API_EXPORT void API_CALL mk_decoder_release(mk_decoder ctx, int flush_frame) {
|
||||
|
||||
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);
|
||||
((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);
|
||||
((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);
|
||||
((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();
|
||||
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);
|
||||
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); })));
|
||||
return new FFmpegFrame::Ptr(std::make_shared<FFmpegFrame>(std::shared_ptr<AVFrame>(av_frame_clone(frame), [](AVFrame *frame){
|
||||
av_frame_free(&frame);
|
||||
})));
|
||||
}
|
||||
|
||||
API_EXPORT mk_frame_pix API_CALL mk_frame_pix_from_buffer(mk_buffer plane_data[], int line_size[], int plane) {
|
||||
assert(plane <= AV_NUM_DATA_POINTERS);
|
||||
std::shared_ptr<AVFrame> frame(av_frame_alloc(), [](AVFrame *ptr) {
|
||||
av_frame_free(&ptr);
|
||||
});
|
||||
std::vector<mk_buffer> buffer_array;
|
||||
for (auto i = 0; i < plane; ++i) {
|
||||
auto buffer = mk_buffer_ref(plane_data[i]);
|
||||
frame->data[i] = (uint8_t *) mk_buffer_get_data(buffer);
|
||||
frame->linesize[i] = line_size[i];
|
||||
buffer_array.emplace_back(buffer);
|
||||
}
|
||||
return new FFmpegFrame::Ptr(new FFmpegFrame(std::move(frame)), [buffer_array](FFmpegFrame *frame) {
|
||||
for (auto &buffer : buffer_array) {
|
||||
mk_buffer_unref(buffer);
|
||||
}
|
||||
delete frame;
|
||||
});
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_frame_pix_unref(mk_frame_pix frame) {
|
||||
assert(frame);
|
||||
delete (FFmpegFrame::Ptr *)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();
|
||||
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);
|
||||
return new FFmpegSws((AVPixelFormat) output, width, height);
|
||||
}
|
||||
|
||||
API_EXPORT void mk_swscale_release(mk_swscale ctx) {
|
||||
delete (FFmpegSws *)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);
|
||||
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 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 void API_CALL mk_set_av_frame_data(AVFrame *frame, uint8_t *data, int plane) {
|
||||
frame->data[plane] = 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) {
|
||||
API_EXPORT void API_CALL mk_set_av_frame_line_size(AVFrame *frame, int line_size, int plane) {
|
||||
frame->linesize[plane] = line_size;
|
||||
}
|
||||
|
||||
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) {
|
||||
API_EXPORT void API_CALL mk_set_av_frame_dts(AVFrame *frame, int64_t dts) {
|
||||
frame->pkt_dts = dts;
|
||||
}
|
||||
|
||||
API_EXPORT int64_t API_CALL mk_get_av_frame_pts(AVFrame *frame) {
|
||||
return frame->pts;
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_set_av_frame_pts(AVFrame *frame, int64_t pts) {
|
||||
frame->pts = pts;
|
||||
}
|
||||
|
||||
API_EXPORT int API_CALL mk_get_av_frame_width(AVFrame *frame) {
|
||||
return frame->width;
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_set_av_frame_width(AVFrame *frame, int width) {
|
||||
frame->width = width;
|
||||
}
|
||||
|
||||
API_EXPORT int API_CALL mk_get_av_frame_height(AVFrame *frame) {
|
||||
return frame->height;
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_set_av_frame_height(AVFrame *frame, int height) {
|
||||
frame->height = height;
|
||||
}
|
||||
|
||||
API_EXPORT int API_CALL mk_get_av_frame_format(AVFrame *frame) {
|
||||
return frame->format;
|
||||
}
|
||||
|
||||
API_EXPORT void API_CALL mk_set_av_frame_format(AVFrame *frame, int format) {
|
||||
frame->format = format;
|
||||
}
|
||||
|
||||
#endif //ENABLE_FFMPEG
|
||||
Reference in New Issue
Block a user