mk_transcode.cpp 6.22 KB
Newer Older
ziyue committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * 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;

ziyue committed
16 17 18 19 20 21 22 23 24 25
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;
}

ziyue committed
26 27 28 29 30 31
#ifdef ENABLE_FFMPEG

#include "Codec/Transcode.h"

API_EXPORT mk_decoder API_CALL mk_decoder_create(mk_track track, int thread_num) {
    assert(track);
32
    return (mk_decoder)new FFmpegDecoder(*((Track::Ptr *) track), thread_num);
ziyue committed
33 34 35 36
}

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);
37
    return (mk_decoder)new FFmpegDecoder(*((Track::Ptr *) track), thread_num, toCodecList(codec_name_list));
ziyue committed
38 39 40 41
}

API_EXPORT void API_CALL mk_decoder_release(mk_decoder ctx, int flush_frame) {
    assert(ctx);
ziyue committed
42
    auto decoder = (FFmpegDecoder *) ctx;
ziyue committed
43 44 45 46 47 48 49 50
    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);
ziyue committed
51
    ((FFmpegDecoder *) ctx)->inputFrame(*((Frame::Ptr *) frame), false, async, enable_merge);
ziyue committed
52 53 54 55
}

API_EXPORT void API_CALL mk_decoder_set_max_async_frame_size(mk_decoder ctx, size_t size) {
    assert(ctx && size);
ziyue committed
56
    ((FFmpegDecoder *) ctx)->setMaxTaskSize(size);
ziyue committed
57 58 59
}

API_EXPORT void API_CALL mk_decoder_set_cb(mk_decoder ctx, on_mk_decode cb, void *user_data) {
60 61 62 63
    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){
ziyue committed
64
    assert(ctx && cb);
65 66 67
    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);
ziyue committed
68 69 70 71 72
    });
}

API_EXPORT const AVCodecContext *API_CALL mk_decoder_get_context(mk_decoder ctx) {
    assert(ctx);
ziyue committed
73
    return ((FFmpegDecoder *) ctx)->getContext();
ziyue committed
74 75 76 77 78 79
}

/////////////////////////////////////////////////////////////////////////////////////////////

API_EXPORT mk_frame_pix API_CALL mk_frame_pix_ref(mk_frame_pix frame) {
    assert(frame);
80
    return (mk_frame_pix)new FFmpegFrame::Ptr(*(FFmpegFrame::Ptr *) frame);
ziyue committed
81 82 83 84
}

API_EXPORT mk_frame_pix API_CALL mk_frame_pix_from_av_frame(AVFrame *frame) {
    assert(frame);
85
    return (mk_frame_pix)new FFmpegFrame::Ptr(std::make_shared<FFmpegFrame>(std::shared_ptr<AVFrame>(av_frame_clone(frame), [](AVFrame *frame){
ziyue committed
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
        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);
    }
102
    return (mk_frame_pix)new FFmpegFrame::Ptr(new FFmpegFrame(std::move(frame)), [buffer_array](FFmpegFrame *frame) {
ziyue committed
103 104 105 106 107
        for (auto &buffer : buffer_array) {
            mk_buffer_unref(buffer);
        }
        delete frame;
    });
ziyue committed
108 109 110 111
}

API_EXPORT void API_CALL mk_frame_pix_unref(mk_frame_pix frame) {
    assert(frame);
ziyue committed
112
    delete (FFmpegFrame::Ptr *) frame;
ziyue committed
113 114 115 116
}

API_EXPORT AVFrame *API_CALL mk_frame_pix_get_av_frame(mk_frame_pix frame) {
    assert(frame);
ziyue committed
117
    return (*(FFmpegFrame::Ptr *) frame)->get();
ziyue committed
118 119
}

ziyue committed
120
/////////////////////////////////////////////////////////////////////////////////////////////
ziyue committed
121 122

API_EXPORT mk_swscale mk_swscale_create(int output, int width, int height) {
123
    return (mk_swscale)new FFmpegSws((AVPixelFormat) output, width, height);
ziyue committed
124 125 126
}

API_EXPORT void mk_swscale_release(mk_swscale ctx) {
ziyue committed
127
    delete (FFmpegSws *) ctx;
ziyue committed
128 129 130
}

API_EXPORT int mk_swscale_input_frame(mk_swscale ctx, mk_frame_pix frame, uint8_t *data) {
ziyue committed
131
    return ((FFmpegSws *) ctx)->inputFrame(*(FFmpegFrame::Ptr *) frame, data);
ziyue committed
132 133
}

ziyue committed
134
API_EXPORT mk_frame_pix mk_swscale_input_frame2(mk_swscale ctx, mk_frame_pix frame){
135
    return (mk_frame_pix)new FFmpegFrame::Ptr(((FFmpegSws *) ctx)->inputFrame(*(FFmpegFrame::Ptr *) frame));
ziyue committed
136 137 138 139 140 141
}

API_EXPORT uint8_t **API_CALL mk_get_av_frame_data(AVFrame *frame) {
    return frame->data;
}

ziyue committed
142 143 144 145
API_EXPORT void API_CALL mk_set_av_frame_data(AVFrame *frame, uint8_t *data, int plane) {
    frame->data[plane] = data;
}

ziyue committed
146 147 148 149
API_EXPORT int *API_CALL mk_get_av_frame_line_size(AVFrame *frame) {
    return frame->linesize;
}

ziyue committed
150 151 152 153 154
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) {
ziyue committed
155 156 157
    return frame->pkt_dts;
}

ziyue committed
158 159 160 161 162
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) {
ziyue committed
163 164 165
    return frame->pts;
}

ziyue committed
166 167 168 169
API_EXPORT void API_CALL mk_set_av_frame_pts(AVFrame *frame, int64_t pts) {
    frame->pts = pts;
}

ziyue committed
170 171 172 173
API_EXPORT int API_CALL mk_get_av_frame_width(AVFrame *frame) {
    return frame->width;
}

ziyue committed
174 175 176 177
API_EXPORT void API_CALL mk_set_av_frame_width(AVFrame *frame, int width) {
    frame->width = width;
}

ziyue committed
178 179 180 181
API_EXPORT int API_CALL mk_get_av_frame_height(AVFrame *frame) {
    return frame->height;
}

ziyue committed
182 183 184 185
API_EXPORT void API_CALL mk_set_av_frame_height(AVFrame *frame, int height) {
    frame->height = height;
}

ziyue committed
186 187 188 189
API_EXPORT int API_CALL mk_get_av_frame_format(AVFrame *frame) {
    return frame->format;
}

ziyue committed
190 191 192
API_EXPORT void API_CALL mk_set_av_frame_format(AVFrame *frame, int format) {
    frame->format = format;
}
ziyue committed
193 194

#endif //ENABLE_FFMPEG