1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved. 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit). 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Use of this source code is governed by MIT license that can be found in the 7*4882a593Smuzhiyun * LICENSE file in the root of the source tree. All contributing project authors 8*4882a593Smuzhiyun * may be found in the AUTHORS file in the root of the source tree. 9*4882a593Smuzhiyun */ 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #ifndef ZLMEDIAKIT_MK_TRANSCODE_H 12*4882a593Smuzhiyun #define ZLMEDIAKIT_MK_TRANSCODE_H 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #include "mk_common.h" 15*4882a593Smuzhiyun #include "mk_track.h" 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #ifdef __cplusplus 18*4882a593Smuzhiyun extern "C" { 19*4882a593Smuzhiyun #endif 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun //解码器对象 22*4882a593Smuzhiyun typedef void *mk_decoder; 23*4882a593Smuzhiyun //解码后的frame 24*4882a593Smuzhiyun typedef void *mk_frame_pix; 25*4882a593Smuzhiyun //SwsContext的包装 26*4882a593Smuzhiyun typedef void *mk_swscale; 27*4882a593Smuzhiyun //FFmpeg原始解码帧对象 28*4882a593Smuzhiyun typedef struct AVFrame AVFrame; 29*4882a593Smuzhiyun //FFmpeg编解码器对象 30*4882a593Smuzhiyun typedef struct AVCodecContext AVCodecContext; 31*4882a593Smuzhiyun //解码输出回调 32*4882a593Smuzhiyun typedef void(API_CALL *on_mk_decode)(void *user_data, mk_frame_pix frame); 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun /** 35*4882a593Smuzhiyun * 创建解码器 36*4882a593Smuzhiyun * @param track track对象 37*4882a593Smuzhiyun * @param thread_num 解码线程数,0时为自动 38*4882a593Smuzhiyun * @return 返回解码器对象,NULL代表失败 39*4882a593Smuzhiyun */ 40*4882a593Smuzhiyun API_EXPORT mk_decoder API_CALL mk_decoder_create(mk_track track, int thread_num); 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /** 43*4882a593Smuzhiyun * 销毁解码器 44*4882a593Smuzhiyun * @param ctx 解码器对象 45*4882a593Smuzhiyun * @param flush_frame 是否等待所有帧解码成功 46*4882a593Smuzhiyun */ 47*4882a593Smuzhiyun API_EXPORT void API_CALL mk_decoder_release(mk_decoder ctx, int flush_frame); 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun /** 50*4882a593Smuzhiyun * 解码音视频帧 51*4882a593Smuzhiyun * @param ctx 解码器 52*4882a593Smuzhiyun * @param frame 帧对象 53*4882a593Smuzhiyun * @param async 是否异步解码 54*4882a593Smuzhiyun * @param enable_merge 是否合并帧解码,有些情况下,需要把时间戳相同的slice合并输入到解码器才能解码 55*4882a593Smuzhiyun */ 56*4882a593Smuzhiyun API_EXPORT void API_CALL mk_decoder_decode(mk_decoder ctx, mk_frame frame, int async, int enable_merge); 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /** 59*4882a593Smuzhiyun * 设置异步解码最大帧缓存积压数限制 60*4882a593Smuzhiyun */ 61*4882a593Smuzhiyun API_EXPORT void API_CALL mk_decoder_set_max_async_frame_size(mk_decoder ctx, size_t size); 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun /** 64*4882a593Smuzhiyun * 设置解码输出回调 65*4882a593Smuzhiyun * @param ctx 解码器 66*4882a593Smuzhiyun * @param cb 回调函数 67*4882a593Smuzhiyun * @param user_data 回调函数用户指针参数 68*4882a593Smuzhiyun */ 69*4882a593Smuzhiyun API_EXPORT void API_CALL mk_decoder_set_cb(mk_decoder ctx, on_mk_decode cb, void *user_data); 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun /** 72*4882a593Smuzhiyun * 获取FFmpeg原始AVCodecContext对象 73*4882a593Smuzhiyun * @param ctx 解码器 74*4882a593Smuzhiyun */ 75*4882a593Smuzhiyun API_EXPORT const AVCodecContext* API_CALL mk_decoder_get_context(mk_decoder ctx); 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun ///////////////////////////////////////////////////////////////////////////////////////////// 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun /** 80*4882a593Smuzhiyun * 创建解码帧mk_frame_pix新引用 81*4882a593Smuzhiyun * @param frame 原始引用 82*4882a593Smuzhiyun * @return 新引用 83*4882a593Smuzhiyun */ 84*4882a593Smuzhiyun API_EXPORT mk_frame_pix API_CALL mk_frame_pix_ref(mk_frame_pix frame); 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun /** 87*4882a593Smuzhiyun * 解码帧mk_frame_pix减引用 88*4882a593Smuzhiyun * @param frame 原始引用 89*4882a593Smuzhiyun */ 90*4882a593Smuzhiyun API_EXPORT void API_CALL mk_frame_pix_unref(mk_frame_pix frame); 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun /** 93*4882a593Smuzhiyun * 从FFmpeg AVFrame转换为mk_frame_pix 94*4882a593Smuzhiyun * @param frame FFmpeg AVFrame 95*4882a593Smuzhiyun * @return mk_frame_pix对象 96*4882a593Smuzhiyun */ 97*4882a593Smuzhiyun API_EXPORT mk_frame_pix API_CALL mk_frame_pix_from_av_frame(AVFrame *frame); 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun /** 100*4882a593Smuzhiyun * 获取FFmpeg AVFrame对象 101*4882a593Smuzhiyun * @param frame 解码帧mk_frame_pix 102*4882a593Smuzhiyun * @return FFmpeg AVFrame对象 103*4882a593Smuzhiyun */ 104*4882a593Smuzhiyun API_EXPORT AVFrame* API_CALL mk_frame_pix_get_av_frame(mk_frame_pix frame); 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun ///////////////////////////////////////////////////////////////////////////////////////////// 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun /** 109*4882a593Smuzhiyun * 创建ffmpeg SwsContext wrapper实例 110*4882a593Smuzhiyun * @param output AVPixelFormat类型,AV_PIX_FMT_BGR24==3 111*4882a593Smuzhiyun * @param width 目标宽度,置0时,则与输入时一致 112*4882a593Smuzhiyun * @param height 目标高度,置0时,则与输入时一致 113*4882a593Smuzhiyun * @return SwsContext wrapper 实例 114*4882a593Smuzhiyun */ 115*4882a593Smuzhiyun API_EXPORT mk_swscale mk_swscale_create(int output, int width, int height); 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun /** 118*4882a593Smuzhiyun * 释放ffmpeg SwsContext wrapper实例 119*4882a593Smuzhiyun * @param ctx SwsContext wrapper实例 120*4882a593Smuzhiyun */ 121*4882a593Smuzhiyun API_EXPORT void mk_swscale_release(mk_swscale ctx); 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun /** 124*4882a593Smuzhiyun * 使用SwsContext转换pix format 125*4882a593Smuzhiyun * @param ctx SwsContext wrapper实例 126*4882a593Smuzhiyun * @param frame pix frame 127*4882a593Smuzhiyun * @param out 转换后存放的数据指针,用户需要确保提前申请并大小足够 128*4882a593Smuzhiyun * @return sws_scale()返回值:the height of the output slice 129*4882a593Smuzhiyun */ 130*4882a593Smuzhiyun API_EXPORT int mk_swscale_input_frame(mk_swscale ctx, mk_frame_pix frame, uint8_t *out); 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun /** 133*4882a593Smuzhiyun * 使用SwsContext转换pix format 134*4882a593Smuzhiyun * @param ctx SwsContext wrapper实例 135*4882a593Smuzhiyun * @param frame pix frame 136*4882a593Smuzhiyun * @return 新的pix frame对象,需要使用mk_frame_pix_unref销毁 137*4882a593Smuzhiyun */ 138*4882a593Smuzhiyun API_EXPORT mk_frame_pix mk_swscale_input_frame2(mk_swscale ctx, mk_frame_pix frame); 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun ///////////////////////////////////////////////////////////////////////////////////////////// 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun API_EXPORT uint8_t** API_CALL mk_get_av_frame_data(AVFrame *frame); 143*4882a593Smuzhiyun API_EXPORT int* API_CALL mk_get_av_frame_line_size(AVFrame *frame); 144*4882a593Smuzhiyun API_EXPORT int64_t API_CALL mk_get_av_frame_dts(AVFrame *frame); 145*4882a593Smuzhiyun API_EXPORT int64_t API_CALL mk_get_av_frame_pts(AVFrame *frame); 146*4882a593Smuzhiyun API_EXPORT int API_CALL mk_get_av_frame_width(AVFrame *frame); 147*4882a593Smuzhiyun API_EXPORT int API_CALL mk_get_av_frame_height(AVFrame *frame); 148*4882a593Smuzhiyun API_EXPORT int API_CALL mk_get_av_frame_format(AVFrame *frame); 149*4882a593Smuzhiyun 150*4882a593Smuzhiyun #ifdef __cplusplus 151*4882a593Smuzhiyun } 152*4882a593Smuzhiyun #endif 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun #endif //ZLMEDIAKIT_MK_TRANSCODE_H