| | |
| | | ${CMAKE_SOURCE_DIR}/csrc/thirdparty/whereami |
| | | ${CMAKE_SOURCE_DIR}/csrc/thirdparty/ffmpeg/include |
| | | ${CMAKE_SOURCE_DIR}/csrc/thirdparty/gb28181/include |
| | | ${CMAKE_SOURCE_DIR}/csrc/gpu-conv |
| | | ) |
| | | |
| | | set(CUDA_TOOLKIT_ROOT_DIR /usr/local/cuda) |
| | | include_directories(/usr/local/cuda/include) |
| | | find_package(CUDA QUIET REQUIRED) |
| | | |
| | | link_directories(/usr/local/cuda/lib64 ${CMAKE_SOURCE_DIR}/csrc/thirdparty/gb28181/lib) |
| | | |
| | |
| | | |
| | | file(GLOB_RECURSE FFMPEG_LIST ${CMAKE_SOURCE_DIR}/csrc/*.cpp) |
| | | list(APPEND FFMPEG_LIST ${CMAKE_SOURCE_DIR}/csrc/thirdparty/whereami/whereami.c) |
| | | file(GLOB_RECURSE CUDA_LIST ${CMAKE_SOURCE_DIR}/csrc/gpu-conv/*.cu) |
| | | |
| | | add_library(${BIN} SHARED ${FFMPEG_LIST}) |
| | | cuda_add_library(${BIN} SHARED ${FFMPEG_LIST} ${CUDA_LIST}) |
| | | |
| | | target_link_libraries(${BIN} ${LINK_LIB} numa nppig nppicc nppc -lz pthread dl rtspclient StreamParse) |
| | |
| | | void c_ffmpeg_destroy(const cffmpeg h); |
| | | void c_ffmpeg_run(const cffmpeg h, const char *input); |
| | | |
| | | void c_ffmpeg_scale(const cffmpeg h, const int wid, const int hei, const int flags); |
| | | void c_ffmpeg_run_gb28181(const cffmpeg h); |
| | | void c_ffmepg_use_cpu(const cffmpeg h); |
| | | /////////passive api |
| | |
| | | void c_ffmpeg_get_info_recorder(const cffmpeg h, int *index, char** recid, int *recidLen, char **fpath, int *pathLen); |
| | | |
| | | void c_ffmpeg_build_decoder(const cffmpeg h); |
| | | void* c_ffmpeg_get_pic_decoder(const cffmpeg h, int *wid, int *hei, int64_t *id); |
| | | void* c_ffmpeg_get_pic_decoder(const cffmpeg h, int *wid, int *hei, int *format, int *length, int64_t *id); |
| | | void* c_ffmpeg_get_avpacket(const cffmpeg h, int *size, int *key); |
| | | |
| | | //////test |
| | | //////decoder |
| | | void* c_ffmpeg_decode(const char *file, const int gb, int *wid, int *hei); |
| | | |
| | | // pic encoder |
| | |
| | | void c_ffmpeg_destroy_encoder(void *h); |
| | | int c_ffmpeg_encode(void *hdl, uint8_t *in, const int w, const int h, uint8_t **out, int *size, int *key); |
| | | |
| | | // conv cpu |
| | | void *c_ffmpeg_create_conv(const int srcW, const int srcH, const int srcFormat, |
| | | const int dstW, const int dstH, const int flag); |
| | | void c_ffmpeg_destroy_conv(void *h); |
| | | void *c_ffmpeg_conv(void *h, uint8_t *in); |
| | | |
| | | // gpu conv |
| | | void* c_gpu_conv(uint8_t *in, const int w, const int h, const int dst_w, const int dst_h, int *length); |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | | #endif |
| | |
| | | s->RunStream(input); |
| | | } |
| | | |
| | | void c_ffmpeg_scale(const cffmpeg h, const int wid, const int hei, const int flags){ |
| | | Wrapper *s = (Wrapper*)h; |
| | | s->ScalePicture(wid, hei, flags); |
| | | } |
| | | |
| | | void c_ffmpeg_run_gb28181(const cffmpeg h){ |
| | | Wrapper *s = (Wrapper*)h; |
| | | s->GB28181(); |
| | |
| | | s->BuildDecoder(); |
| | | } |
| | | |
| | | void* c_ffmpeg_get_pic_decoder(const cffmpeg h, int *wid, int *hei, int64_t *id){ |
| | | void* c_ffmpeg_get_pic_decoder(const cffmpeg h, int *wid, int *hei, int *format, int *length, int64_t *id){ |
| | | Wrapper *s = (Wrapper*)h; |
| | | unsigned char *data = NULL; |
| | | s->GetPicDecoder(&data, wid, hei, id); |
| | | s->GetPicDecoder(&data, wid, hei, format, length, id); |
| | | return data; |
| | | } |
| | | |
| | |
| | | int c_ffmpeg_encode(void *hdl, uint8_t *in, const int w, const int h, uint8_t **out, int *size, int *key){ |
| | | return Encode(hdl, in, w, h, out, size, key); |
| | | } |
| | | |
| | | void *c_ffmpeg_create_conv(const int srcW, const int srcH, const int srcFormat, |
| | | const int dstW, const int dstH, const int flag){ |
| | | return CreateConvertor(srcW, srcH, srcFormat, dstW, dstH, flag); |
| | | } |
| | | |
| | | void *c_ffmpeg_conv(void *h, uint8_t *in){ |
| | | return Convert(h, in); |
| | | } |
| | | |
| | | void c_ffmpeg_destroy_conv(void *h){ |
| | | DestoryConvertor(h); |
| | | } |
| | | |
| | | void* c_gpu_conv(uint8_t *in, const int w, const int h, const int dst_w, const int dst_h, int *length){ |
| | | return ConvertYUV2BGR(in, w, h, dst_w, dst_h, length); |
| | | } |
| | |
| | | av_register_all(); |
| | | avfilter_register_all(); |
| | | avformat_network_init(); |
| | | av_log_set_level(AV_LOG_ERROR); |
| | | av_log_set_level(AV_LOG_VERBOSE); |
| | | } |
| | | |
| | | std::string getAVErrorDesc(const int code){ |
New file |
| | |
| | | /******************************************************************* |
| | | * CUDALERP.cu |
| | | * CUDALERP |
| | | * |
| | | * Author: Kareem Omar |
| | | * kareem.omar@uah.edu |
| | | * https://github.com/komrad36 |
| | | * |
| | | * Last updated Jan 7, 2016 |
| | | *******************************************************************/ |
| | | // |
| | | // The file CUDALERP.h exposes two extremely high performance GPU |
| | | // resize operations, |
| | | // CUDALERP (bilinear interpolation), and |
| | | // CUDANERP (nearest neighbor interpolation), for 8-bit unsigned |
| | | // integer (i.e. grayscale) data. |
| | | // |
| | | // For 32-bit float data, see the CUDAFLERP project instead. |
| | | // |
| | | // CUDALERP offers superior accuracy to CUDA's built-in texture |
| | | // interpolator at comparable performance. The accuracy if compiled |
| | | // with -use-fast-math off is nearly equivalent to my CPU interpolator, |
| | | // KLERP, while still being as fast as the built-in interpolation. |
| | | // |
| | | // Particularly for large images, CUDALERP dramatically outperforms |
| | | // even the highly tuned CPU AVX2 versions. |
| | | // |
| | | // All functionality is contained in the header 'CUDALERP.h' and |
| | | // the source file 'CUDALERP.cu' and has no external dependencies at all. |
| | | // |
| | | // Note that these are intended for computer vision use(hence the speed) |
| | | // and are designed for grayscale images. |
| | | // |
| | | // The file 'main.cpp' is an example and speed test driver. |
| | | // |
| | | |
| | | #include "CUDALERP.h" |
| | | |
| | | __global__ void |
| | | #ifndef __INTELLISENSE__ |
| | | __launch_bounds__(256, 0) |
| | | #endif |
| | | CUDANERP_kernel(const cudaTextureObject_t d_img_tex, const float gxs, const float gys, uint8_t* __restrict const d_out, const int neww) { |
| | | uint32_t x = (blockIdx.x << 9) + (threadIdx.x << 1); |
| | | const uint32_t y = blockIdx.y; |
| | | const float fy = y*gys; |
| | | #pragma unroll |
| | | for (int i = 0; i < 2; ++i, ++x) { |
| | | const float fx = x*gxs; |
| | | float res = 255.0f*tex2D<float>(d_img_tex, fx, fy); |
| | | if (x < neww) d_out[y*neww + x] = res; |
| | | } |
| | | } |
| | | |
| | | __global__ void |
| | | #ifndef __INTELLISENSE__ |
| | | __launch_bounds__(256, 0) |
| | | #endif |
| | | CUDALERP_kernel(const cudaTextureObject_t d_img_tex, const float gxs, const float gys, uint8_t* __restrict const d_out, const int neww) { |
| | | uint32_t x = (blockIdx.x << 9) + (threadIdx.x << 1); |
| | | const uint32_t y = blockIdx.y; |
| | | const float fy = (y + 0.5f)*gys - 0.5f; |
| | | const float wt_y = fy - floor(fy); |
| | | const float invwt_y = 1.0f - wt_y; |
| | | #pragma unroll |
| | | for (int i = 0; i < 2; ++i, ++x) { |
| | | const float fx = (x + 0.5f)*gxs - 0.5f; |
| | | // less accurate and not really much (or any) faster |
| | | // ----------------- |
| | | // const float res = tex2D<float>(d_img_tex, fx, fy); |
| | | // ----------------- |
| | | const float4 f = tex2Dgather<float4>(d_img_tex, fx + 0.5f, fy + 0.5f); |
| | | const float wt_x = fx - floor(fx); |
| | | const float invwt_x = 1.0f - wt_x; |
| | | const float xa = invwt_x*f.w + wt_x*f.z; |
| | | const float xb = invwt_x*f.x + wt_x*f.y; |
| | | const float res = 255.0f*(invwt_y*xa + wt_y*xb) + 0.5f; |
| | | // ----------------- |
| | | if (x < neww) d_out[y*neww + x] = res; |
| | | } |
| | | } |
| | | |
| | | void CUDANERP(const cudaTextureObject_t d_img_tex, const int oldw, const int oldh, uint8_t* __restrict const d_out, const uint32_t neww, const uint32_t newh) { |
| | | const float gxs = static_cast<float>(oldw) / static_cast<float>(neww); |
| | | const float gys = static_cast<float>(oldh) / static_cast<float>(newh); |
| | | CUDANERP_kernel<<<{((neww - 1) >> 9) + 1, newh}, 256>>>(d_img_tex, gxs, gys, d_out, neww); |
| | | cudaDeviceSynchronize(); |
| | | } |
| | | |
| | | void CUDALERP(const cudaTextureObject_t d_img_tex, const int oldw, const int oldh, uint8_t* __restrict const d_out, const uint32_t neww, const uint32_t newh) { |
| | | const float gxs = static_cast<float>(oldw) / static_cast<float>(neww); |
| | | const float gys = static_cast<float>(oldh) / static_cast<float>(newh); |
| | | CUDALERP_kernel<<<{((neww - 1) >> 9) + 1, newh}, 256>>>(d_img_tex, gxs, gys, d_out, neww); |
| | | cudaDeviceSynchronize(); |
| | | } |
New file |
| | |
| | | /******************************************************************* |
| | | * CUDALERP.h |
| | | * CUDALERP |
| | | * |
| | | * Author: Kareem Omar |
| | | * kareem.omar@uah.edu |
| | | * https://github.com/komrad36 |
| | | * |
| | | * Last updated Jan 7, 2016 |
| | | *******************************************************************/ |
| | | // |
| | | // The file CUDALERP.h exposes two extremely high performance GPU |
| | | // resize operations, |
| | | // CUDALERP (bilinear interpolation), and |
| | | // CUDANERP (nearest neighbor interpolation), for 8-bit unsigned |
| | | // integer (i.e. grayscale) data. |
| | | // |
| | | // For 32-bit float data, see the CUDAFLERP project instead. |
| | | // |
| | | // CUDALERP offers superior accuracy to CUDA's built-in texture |
| | | // interpolator at comparable performance. The accuracy if compiled |
| | | // with -use-fast-math off is nearly equivalent to my CPU interpolator, |
| | | // KLERP, while still being as fast as the built-in interpolation. |
| | | // |
| | | // Particularly for large images, CUDALERP dramatically outperforms |
| | | // even the highly tuned CPU AVX2 versions. |
| | | // |
| | | // All functionality is contained in the header 'CUDALERP.h' and |
| | | // the source file 'CUDALERP.cu' and has no external dependencies at all. |
| | | // |
| | | // Note that these are intended for computer vision use(hence the speed) |
| | | // and are designed for grayscale images. |
| | | // |
| | | // The file 'main.cpp' is an example and speed test driver. |
| | | // |
| | | |
| | | #pragma once |
| | | |
| | | #include "cuda_runtime.h" |
| | | |
| | | #include <cstdint> |
| | | |
| | | #ifdef __INTELLISENSE__ |
| | | #include <algorithm> |
| | | #define asm(x) |
| | | #include "device_launch_parameters.h" |
| | | #define __CUDACC__ |
| | | #include "device_functions.h" |
| | | #undef __CUDACC__ |
| | | #endif |
| | | |
| | | void CUDALERP(const cudaTextureObject_t d_img_tex, const int oldw, const int oldh, uint8_t* __restrict const d_out, const uint32_t neww, const uint32_t newh); |
| | | |
| | | void CUDANERP(const cudaTextureObject_t d_img_tex, const int oldw, const int oldh, uint8_t* __restrict const d_out, const uint32_t neww, const uint32_t newh); |
| | |
| | | |
| | | namespace cffmpeg_wrap |
| | | { |
| | | decoder::decoder(ffwrapper::FormatIn *dec, const int w, const int h, const int f) |
| | | :conv_(NULL) |
| | | ,conv_w_(w) |
| | | ,conv_h_(h) |
| | | ,conv_flag_(f) |
| | | ,decRef_(dec) |
| | | decoder::decoder(ffwrapper::FormatIn *dec) |
| | | :decRef_(dec) |
| | | {} |
| | | |
| | | decoder::~decoder(){ |
| | | |
| | | if (conv_){ |
| | | delete conv_; |
| | | std::lock_guard<std::mutex> l(mutex_frm_); |
| | | for(auto i : list_frm_){ |
| | | av_frame_free(&i.frm); |
| | | } |
| | | |
| | | { |
| | | std::lock_guard<std::mutex> l(mutex_pic_); |
| | | for(auto &i : list_pic_){ |
| | | free(i.data); |
| | | } |
| | | list_pic_.clear(); |
| | | } |
| | | list_frm_.clear(); |
| | | } |
| | | |
| | | int decoder::initDecoder(){ |
| | |
| | | |
| | | bool flag = true; |
| | | flag = decRef_->openCodec(NULL); |
| | | auto dec_ctx = decRef_->getCodecContext(); |
| | | if(conv_){ |
| | | delete conv_; |
| | | conv_ = NULL; |
| | | } |
| | | conv_w_ = conv_w_ == 0 || conv_w_ > dec_ctx->width ? dec_ctx->width : conv_w_; |
| | | conv_h_ = conv_h_ == 0 || conv_h_ > dec_ctx->height ? dec_ctx->height : conv_h_; |
| | | AVPixelFormat pix_fmt = AV_PIX_FMT_BGR24; |
| | | conv_ = new cvbridge( |
| | | dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt, |
| | | conv_w_, conv_h_, pix_fmt, conv_flag_); |
| | | |
| | | if (!flag){ |
| | | logIt("FormatIn openCodec Failed!"); |
| | |
| | | } |
| | | |
| | | int decoder::saveFrame(AVFrame *frame, int64_t &id){ |
| | | //缓存数据 |
| | | BGR24 pic; |
| | | AVFrame *frm = frame; |
| | | pic.w = conv_w_; |
| | | pic.h = conv_h_; |
| | | unsigned char *picData = (unsigned char*)malloc(pic.w * pic.h * 3); |
| | | conv_->copyPicture(picData, frm); |
| | | pic.data = picData; |
| | | pic.id = id; |
| | | std::lock_guard<std::mutex> l(mutex_pic_); |
| | | while(list_pic_.size() > 50){ |
| | | while(list_frm_.size() > 50){ |
| | | for(int i = 0; i < 12; i++){ |
| | | auto t = list_pic_.front(); |
| | | free(t.data); |
| | | list_pic_.pop_front(); |
| | | auto t = list_frm_.front(); |
| | | av_frame_free(&t.frm); |
| | | list_frm_.pop_front(); |
| | | } |
| | | } |
| | | list_pic_.emplace_back(pic); |
| | | return list_pic_.size(); |
| | | list_frm_.push_back({frame,id}); |
| | | return list_frm_.size(); |
| | | } |
| | | |
| | | int decoder::SetFrame(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id){ |
| | |
| | | if (!data) return -1; |
| | | if (!decRef_->isVideoPkt(&data->getAVPacket())) return -2; |
| | | |
| | | if (!conv_){ |
| | | if (decRef_->getCodecContext() == NULL){ |
| | | if (initDecoder() != 0) return -3; |
| | | } |
| | | |
| | |
| | | if (ret == 0){ |
| | | saveFrame(frame, id); |
| | | } |
| | | av_frame_free(&frame); |
| | | } |
| | | |
| | | void decoder::GetFrame(unsigned char **data, int *w, int *h, int64_t *id){ |
| | | std::lock_guard<std::mutex> l(mutex_pic_); |
| | | if(list_pic_.empty()){ |
| | | void decoder::GetFrame(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){ |
| | | |
| | | AVFrame *frm = NULL; |
| | | { |
| | | std::lock_guard<std::mutex> l(mutex_frm_); |
| | | if(list_frm_.empty()){ |
| | | *data = NULL; |
| | | *w = *h = 0; |
| | | *id = -1; |
| | | return; |
| | | } |
| | | auto p = list_frm_.front(); |
| | | list_frm_.pop_front(); |
| | | frm = p.frm; |
| | | *id = p.id; |
| | | *w = frm->width; |
| | | *h = frm->height; |
| | | *format = frm->format; |
| | | } |
| | | |
| | | *length = avpicture_get_size((enum AVPixelFormat)frm->format, frm->width, frm->height); |
| | | if (*length <= 0){ |
| | | logIt("get raw frame data error"); |
| | | *data = NULL; |
| | | *w = 0; |
| | | *h = 0; |
| | | *w = *h = 0; |
| | | *id = -1; |
| | | return; |
| | | } |
| | | auto p = list_pic_.front(); |
| | | *data = p.data; *w = p.w; *h = p.h; |
| | | *id = p.id; |
| | | list_pic_.pop_front(); |
| | | |
| | | unsigned char *picData = (unsigned char*)malloc(*length); |
| | | auto ret = avpicture_layout((const AVPicture*)frm, (enum AVPixelFormat)frm->format, frm->width, frm->height, picData, *length); |
| | | av_frame_free(&frm); |
| | | |
| | | if (ret < 0){ |
| | | *data = NULL; |
| | | *w = *h = 0; |
| | | *id = -1; |
| | | free(picData); |
| | | return; |
| | | } |
| | | |
| | | *data = picData; |
| | | } |
| | | |
| | | } // namespace cffmpeg_wrap |
| | |
| | | #include <condition_variable> |
| | | |
| | | struct AVFrame; |
| | | struct AVCodecContext; |
| | | |
| | | namespace ffwrapper |
| | | { |
| | | class FormatIn; |
| | | class cvbridge; |
| | | class CodedData; |
| | | } // namespace ffwrapper |
| | | |
| | | namespace cffmpeg_wrap |
| | | { |
| | | typedef struct _pic_bgr24{ |
| | | unsigned char *data; |
| | | int w; |
| | | int h; |
| | | |
| | | typedef struct _frm{ |
| | | AVFrame *frm; |
| | | int64_t id; |
| | | }BGR24; |
| | | }FRM; |
| | | |
| | | class decoder |
| | | { |
| | | private: |
| | | ffwrapper::cvbridge *conv_; |
| | | int conv_w_, conv_h_, conv_flag_; |
| | | |
| | | ffwrapper::FormatIn *decRef_; |
| | | |
| | | std::list<BGR24> list_pic_; |
| | | std::mutex mutex_pic_; |
| | | |
| | | std::list<FRM> list_frm_; |
| | | std::mutex mutex_frm_; |
| | | |
| | | private: |
| | | int initDecoder(); |
| | | int saveFrame(AVFrame *frame, int64_t &id); |
| | | public: |
| | | void Start(); |
| | | int SetFrame(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id); |
| | | void GetFrame(unsigned char **data, int *w, int *h, int64_t *id); |
| | | void GetFrame(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id); |
| | | |
| | | public: |
| | | decoder(ffwrapper::FormatIn *dec, const int w, const int h, const int f); |
| | | explicit decoder(ffwrapper::FormatIn *dec); |
| | | ~decoder(); |
| | | }; |
| | | |
| | |
| | | #include "worker/decoder.hpp" |
| | | #include "worker/rec.hpp" |
| | | |
| | | #include "CUDALERP.h" |
| | | |
| | | using namespace logif; |
| | | using namespace ffwrapper; |
| | | |
| | |
| | | |
| | | Wrapper::Wrapper() |
| | | :input_url_("") |
| | | ,scale_w_(0) |
| | | ,scale_h_(0) |
| | | ,scale_f_(SWS_POINT) |
| | | ,audio_(false) |
| | | ,gb_(0) |
| | | ,cpu_(0) |
| | |
| | | |
| | | Wrapper::Wrapper(const char *logfile) |
| | | :input_url_("") |
| | | ,scale_w_(0) |
| | | ,scale_h_(0) |
| | | ,scale_f_(SWS_POINT) |
| | | ,audio_(false) |
| | | ,gb_(0) |
| | | ,cpu_(0) |
| | |
| | | stream_ = new stream(in, 3 * in->getFPS()); |
| | | // stream_->AudioSwitch(audio_); |
| | | |
| | | decoder_ = new decoder(in, scale_w_, scale_h_, scale_f_); |
| | | decoder_ = new decoder(in); |
| | | |
| | | rec_->Load(in); |
| | | if(fn_rec_lazy_) { |
| | |
| | | run_dec_ = true; |
| | | } |
| | | |
| | | void Wrapper::GetPicDecoder(unsigned char **data, int *w, int *h, int64_t *id){ |
| | | void Wrapper::GetPicDecoder(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){ |
| | | if (decoder_){ |
| | | decoder_->GetFrame(data, w, h, id); |
| | | decoder_->GetFrame(data, w, h, format, length, id); |
| | | } |
| | | } |
| | | |
| | |
| | | return flag; |
| | | } |
| | | |
| | | /////////////////////////////////////////////////////////// |
| | | typedef struct _conv |
| | | { |
| | | int srcW; |
| | | int srcH; |
| | | int srcF; |
| | | int dstW; |
| | | int dstH; |
| | | cvbridge *b; |
| | | }Conv; |
| | | |
| | | void *CreateConvertor(const int srcW, const int srcH, const int srcFormat, |
| | | const int dstW, const int dstH, const int flag){ |
| | | AVPixelFormat pix_fmt = AV_PIX_FMT_BGR24; |
| | | auto bridge = new cvbridge( |
| | | srcW, srcH, srcFormat, |
| | | dstW, dstH, pix_fmt, flag); |
| | | if (!bridge) return NULL; |
| | | |
| | | Conv *c = (Conv*)malloc(sizeof(Conv)); |
| | | c->b = bridge; |
| | | c->dstW = dstW; |
| | | c->dstH = dstH; |
| | | c->srcW = srcW; |
| | | c->srcH = srcH; |
| | | c->srcF = srcFormat; |
| | | |
| | | return c; |
| | | } |
| | | |
| | | uint8_t *Convert(void *h, uint8_t *src){ |
| | | Conv *c = (Conv*)h; |
| | | |
| | | auto b = c->b; |
| | | |
| | | AVFrame *tmp_frm = av_frame_alloc(); |
| | | tmp_frm->format = (AVPixelFormat)c->srcF; |
| | | tmp_frm->width = c->srcW; |
| | | tmp_frm->height = c->srcH; |
| | | |
| | | //create a AVPicture frame from the opencv Mat input image |
| | | int ret = avpicture_fill((AVPicture *)tmp_frm, |
| | | (uint8_t *)src, |
| | | (AVPixelFormat)tmp_frm->format, |
| | | tmp_frm->width, |
| | | tmp_frm->height); |
| | | |
| | | unsigned char *picData = NULL; |
| | | if (ret > 0){ |
| | | picData = (unsigned char*)malloc(c->dstW * c->dstH * 3); |
| | | b->copyPicture(picData, tmp_frm); |
| | | } |
| | | |
| | | av_frame_free(&tmp_frm); |
| | | |
| | | return picData; |
| | | } |
| | | |
| | | void DestoryConvertor(void *h){ |
| | | Conv *c = (Conv*)h; |
| | | delete c->b; |
| | | free(c); |
| | | } |
| | | |
| | | |
| | | uint8_t* ConvertYUV2BGR(uint8_t *src, const int w, const int h, const int dst_w, const int dst_h, int *length){ |
| | | return NULL; |
| | | |
| | | // int oldw = w, oldh = h, neww = dst_w, newh = dst_h; |
| | | // // setting cache and shared modes |
| | | // cudaDeviceSetCacheConfig(cudaFuncCachePreferL1); |
| | | // cudaDeviceSetSharedMemConfig(cudaSharedMemBankSizeFourByte); |
| | | |
| | | // // allocating and transferring image and binding to texture object |
| | | // cudaChannelFormatDesc chandesc_img = cudaCreateChannelDesc(8, 0, 0, 0, cudaChannelFormatKindUnsigned); |
| | | // cudaArray* d_img_arr; |
| | | // cudaMallocArray(&d_img_arr, &chandesc_img, oldw, oldh, cudaArrayTextureGather); |
| | | // cudaMemcpyToArray(d_img_arr, 0, 0, image, oldh * oldw, cudaMemcpyHostToDevice); |
| | | // struct cudaResourceDesc resdesc_img; |
| | | // memset(&resdesc_img, 0, sizeof(resdesc_img)); |
| | | // resdesc_img.resType = cudaResourceTypeArray; |
| | | // resdesc_img.res.array.array = d_img_arr; |
| | | // struct cudaTextureDesc texdesc_img; |
| | | // memset(&texdesc_img, 0, sizeof(texdesc_img)); |
| | | // texdesc_img.addressMode[0] = cudaAddressModeClamp; |
| | | // texdesc_img.addressMode[1] = cudaAddressModeClamp; |
| | | // texdesc_img.readMode = cudaReadModeNormalizedFloat; |
| | | // texdesc_img.filterMode = cudaFilterModePoint; |
| | | // texdesc_img.normalizedCoords = 0; |
| | | // cudaTextureObject_t d_img_tex = 0; |
| | | // cudaCreateTextureObject(&d_img_tex, &resdesc_img, &texdesc_img, nullptr); |
| | | |
| | | // uint8_t* d_out = nullptr; |
| | | // cudaMalloc(&d_out, total); |
| | | |
| | | // for (int i = 0; i < warmups; ++i) CUDALERP(d_img_tex, oldw, oldh, d_out, neww, newh); |
| | | // auto start = high_resolution_clock::now(); |
| | | // for (int i = 0; i < runs; ++i) CUDALERP(d_img_tex, oldw, oldh, d_out, neww, newh); |
| | | // auto end = high_resolution_clock::now(); |
| | | // auto sum = (end - start) / runs; |
| | | |
| | | // auto h_out = new uint8_t[neww * newh]; |
| | | // cudaMemcpy(h_out, d_out, total, cudaMemcpyDeviceToHost); |
| | | } |
| | | } |
| | | |
| | |
| | | void BuildRecorder(const char* id,const char *dir, const int mind, const int maxd, const bool audio); |
| | | int FireRecorder(const char* sid,const int64_t &id); |
| | | void GetInfoRecorder(std::string &recID, int &index, std::string &path); |
| | | void ScalePicture(const int w, const int h, const int flags){ |
| | | scale_w_ = w; |
| | | scale_h_ = h; |
| | | scale_f_ = flags; |
| | | } |
| | | |
| | | void GB28181(){gb_ = 1;} |
| | | void CPUDec(){cpu_ = 1;} |
| | | void AudioSwitch(const bool a); |
| | | public: //decoder |
| | | void BuildDecoder(); |
| | | void GetPicDecoder(unsigned char **data, int *w, int *h, int64_t *id); |
| | | void GetPicDecoder(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id); |
| | | public: // push stream |
| | | void GetPacket(unsigned char **pktData, int *size, int *key); |
| | | private: |
| | | // stream 参数 |
| | | std::string input_url_; |
| | | int scale_w_, scale_h_, scale_f_; |
| | | bool audio_; |
| | | int gb_, cpu_; |
| | | bool run_dec_; |
| | |
| | | }; |
| | | |
| | | uint8_t* Decode(const char *file, const int gb, int *w, int *h); |
| | | |
| | | void *CreateEncoder(const int w, const int h, const int fps, const int br, const int scale_flag, const int gi); |
| | | void DestroyEncoder(void *h); |
| | | int Encode(void *hdl, uint8_t *in, const int w, const int h, uint8_t **out, int *size, int *key); |
| | | |
| | | void *CreateConvertor(const int srcW, const int srcH, const int srcFormat, |
| | | const int dstW, const int dstH, const int flag); |
| | | uint8_t *Convert(void *h, uint8_t *src); |
| | | void DestoryConvertor(void *h); |
| | | |
| | | uint8_t* ConvertYUV2BGR(uint8_t *src, const int w, const int h, const int dst_w, const int dst_h, int *length); |
| | | } |
| | | |
| | | #endif |
New file |
| | |
| | | package goffmpeg |
| | | |
| | | /* |
| | | #include <stdlib.h> |
| | | #include "libcffmpeg.h" |
| | | */ |
| | | import "C" |
| | | import "unsafe" |
| | | |
| | | const ( |
| | | // ScaleNone self add no scale raw frame data |
| | | ScaleNone = 0 |
| | | // ScaleFastBilinear SWS_FAST_BILINEAR |
| | | ScaleFastBilinear = 1 |
| | | // ScaleBilinear SWS_BILINEAR |
| | | ScaleBilinear = 2 |
| | | // ScaleBicubic SWS_BICUBIC |
| | | ScaleBicubic = 4 |
| | | // ScaleX SWS_X |
| | | ScaleX = 8 |
| | | // ScalePoint SWS_POINT |
| | | ScalePoint = 0x10 |
| | | // ScaleArea SWS_AREA |
| | | ScaleArea = 0x20 |
| | | // ScaleBicublin SWS_BICUBLIN |
| | | ScaleBicublin = 0x40 |
| | | // ScaleGauss SWS_GAUSS |
| | | ScaleGauss = 0x80 |
| | | // ScaleSinc SWS_SINC |
| | | ScaleSinc = 0x100 |
| | | // ScaleLancZos SWS_LANCZOS |
| | | ScaleLancZos = 0x200 |
| | | // ScaleSpline SWS_SPLINE |
| | | ScaleSpline = 0x400 |
| | | ) |
| | | |
| | | // SrcFormat format |
| | | const srcFormat = 23 |
| | | |
| | | // GoConv conv |
| | | type GoConv struct { |
| | | srcW int |
| | | srcH int |
| | | dstW int |
| | | dstH int |
| | | |
| | | conv C.cconv |
| | | } |
| | | |
| | | // NewConv new conv |
| | | func NewConv(srcW, srcH, dstW, dstH, scaleFlag int) *GoConv { |
| | | c := C.wrap_fn_create_conv(C.int(srcW), C.int(srcH), C.int(srcFormat), C.int(dstW), C.int(dstH), C.int(scaleFlag)) |
| | | |
| | | if c == nil { |
| | | return nil |
| | | } |
| | | |
| | | return &GoConv{ |
| | | srcW, |
| | | srcH, |
| | | dstW, |
| | | dstH, |
| | | c, |
| | | } |
| | | } |
| | | |
| | | // Free free |
| | | func (c *GoConv) Free() { |
| | | if c.conv != nil { |
| | | C.wrap_fn_destroy_conv(c.conv) |
| | | } |
| | | } |
| | | |
| | | // ConvToPicture conv to pic |
| | | func (c *GoConv) ConvToPicture(src []byte) []byte { |
| | | if c.conv == nil { |
| | | return nil |
| | | } |
| | | |
| | | cin := C.CBytes(src) |
| | | defer C.free(cin) |
| | | |
| | | bgr := C.wrap_fn_conv(c.conv, (*C.uchar)(cin)) |
| | | defer C.free(unsafe.Pointer(bgr)) |
| | | |
| | | if bgr != nil { |
| | | return C.GoBytes(bgr, C.int(c.dstW*c.dstH*3)) |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | /////////////// for conv |
| | | |
| | | // ConvGPU conv gpu resize |
| | | func ConvGPU(in []byte, w, h, dstW, dstH int) []byte { |
| | | |
| | | return nil |
| | | |
| | | } |
New file |
| | |
| | | package goffmpeg |
| | | |
| | | /* |
| | | #include <stdlib.h> |
| | | #include "libcffmpeg.h" |
| | | */ |
| | | import "C" |
| | | import "unsafe" |
| | | |
| | | // BuildDecoder build decoder |
| | | func (h *GoFFMPEG) BuildDecoder() { |
| | | C.wrap_fn_decoder(h.ffmpeg) |
| | | } |
| | | |
| | | // GetYUV get yuv data |
| | | func (h *GoFFMPEG) GetYUV() ([]byte, int, int, int64) { |
| | | var fid C.long |
| | | var length C.int |
| | | var srcW, srcH, srcF C.int |
| | | |
| | | p := C.wrap_fn_decoder_pic(h.ffmpeg, &srcW, &srcH, &srcF, &length, &fid) |
| | | if srcW == 0 || srcH == 0 { |
| | | return nil, 0, 0, 0 |
| | | } |
| | | defer C.free(unsafe.Pointer(p)) |
| | | |
| | | return C.GoBytes(p, length), int(srcW), int(srcH), int64(fid) |
| | | } |
New file |
| | |
| | | package goffmpeg |
| | | |
| | | /* |
| | | #include <stdlib.h> |
| | | #include "libcffmpeg.h" |
| | | */ |
| | | import "C" |
| | | |
| | | ///////////////for encoder |
| | | |
| | | // GoEncoder encoder |
| | | type GoEncoder struct { |
| | | enc C.cencoder |
| | | } |
| | | |
| | | // NewEncoder encoder |
| | | func NewEncoder(w, h, fps, br, sFlag, gi int) *GoEncoder { |
| | | if w <= 0 || h <= 0 { |
| | | return nil |
| | | } |
| | | |
| | | return &GoEncoder{ |
| | | enc: C.wrap_fn_create_encoder(C.int(w), C.int(h), C.int(fps), C.int(br), C.int(sFlag), C.int(gi)), |
| | | } |
| | | } |
| | | |
| | | // Free free |
| | | func (e *GoEncoder) Free() { |
| | | if e.enc != nil { |
| | | C.wrap_fn_destroy_encoder(e.enc) |
| | | } |
| | | } |
| | | |
| | | // Encode pic |
| | | func (e *GoEncoder) Encode(in []byte, w, h int) ([]byte, int, bool) { |
| | | |
| | | var size C.int |
| | | var key C.int |
| | | cin := C.CBytes(in) |
| | | defer C.free(cin) |
| | | |
| | | p := C.wrap_fn_encode(e.enc, cin, C.int(w), C.int(h), &size, &key) |
| | | defer C.free(p) |
| | | if p != nil && size > 0 { |
| | | b := C.GoBytes(p, size) |
| | | |
| | | isKey := false |
| | | if key > 0 { |
| | | isKey = true |
| | | } |
| | | return b, int(size), isKey |
| | | } |
| | | return nil, 0, false |
| | | } |
| | |
| | | "unsafe" |
| | | ) |
| | | |
| | | const ( |
| | | // ScaleFastBilinear SWS_FAST_BILINEAR |
| | | ScaleFastBilinear = 1 |
| | | // ScaleBilinear SWS_BILINEAR |
| | | ScaleBilinear = 2 |
| | | // ScaleBicubic SWS_BICUBIC |
| | | ScaleBicubic = 4 |
| | | // ScaleX SWS_X |
| | | ScaleX = 8 |
| | | // ScalePoint SWS_POINT |
| | | ScalePoint = 0x10 |
| | | // ScaleArea SWS_AREA |
| | | ScaleArea = 0x20 |
| | | // ScaleBicublin SWS_BICUBLIN |
| | | ScaleBicublin = 0x40 |
| | | // ScaleGauss SWS_GAUSS |
| | | ScaleGauss = 0x80 |
| | | // ScaleSinc SWS_SINC |
| | | ScaleSinc = 0x100 |
| | | // ScaleLancZos SWS_LANCZOS |
| | | ScaleLancZos = 0x200 |
| | | // ScaleSpline SWS_SPLINE |
| | | ScaleSpline = 0x400 |
| | | ) |
| | | |
| | | var libcffmpeg C.libcffmpeg |
| | | |
| | | // InitFFmpeg init ffmepg |
| | |
| | | } |
| | | } |
| | | |
| | | // Config config |
| | | type Config struct { |
| | | Scale int |
| | | Width int |
| | | Height int |
| | | GB bool |
| | | CPU bool |
| | | } |
| | | |
| | | // GoFFMPEG handle for c |
| | | type GoFFMPEG struct { |
| | | ffmpeg C.cffmpeg |
| | | } |
| | | |
| | | // New 2nd new |
| | | func New(conf Config) *GoFFMPEG { |
| | | func New(GB, CPU bool) *GoFFMPEG { |
| | | |
| | | f := C.wrap_fn_create() |
| | | |
| | | if f == nil { |
| | | return nil |
| | | } |
| | | if conf.Scale != 0 && conf.Width != 0 && conf.Height != 0 { |
| | | C.wrap_fn_scale(f, C.int(conf.Width), C.int(conf.Height), C.int(conf.Scale)) |
| | | } |
| | | if conf.GB { |
| | | if GB { |
| | | C.wrap_fn_run_gb28181(f) |
| | | } |
| | | if conf.CPU { |
| | | if CPU { |
| | | C.wrap_fn_use_cpu(f) |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | // NewWithLog log |
| | | func NewWithLog(conf Config, logfile string) *GoFFMPEG { |
| | | lf := C.CString(logfile) |
| | | func NewWithLog(GB, CPU bool, ffmpegLog string) *GoFFMPEG { |
| | | lf := C.CString(ffmpegLog) |
| | | defer C.free(unsafe.Pointer(lf)) |
| | | |
| | | f := C.wrap_fn_create2(lf) |
| | | if f == nil { |
| | | return nil |
| | | } |
| | | if conf.Scale != 0 && conf.Width != 0 && conf.Height != 0 { |
| | | C.wrap_fn_scale(f, C.int(conf.Width), C.int(conf.Height), C.int(conf.Scale)) |
| | | } |
| | | if conf.GB { |
| | | if GB { |
| | | C.wrap_fn_run_gb28181(f) |
| | | } |
| | | if conf.CPU { |
| | | if CPU { |
| | | C.wrap_fn_use_cpu(f) |
| | | } |
| | | |
| | |
| | | |
| | | // Free free handle |
| | | func (h *GoFFMPEG) Free() { |
| | | C.wrap_fn_destroy(h.ffmpeg) |
| | | if h.ffmpeg != nil { |
| | | C.wrap_fn_destroy(h.ffmpeg) |
| | | } |
| | | } |
| | | |
| | | // Run ffmpeg |
| | |
| | | defer C.free(unsafe.Pointer(in)) |
| | | |
| | | C.wrap_fn_run(h.ffmpeg, in) |
| | | } |
| | | |
| | | // FireRecorder fire recorder |
| | | func (h *GoFFMPEG) FireRecorder(sid string, id int64) { |
| | | csid := C.CString(sid) |
| | | defer C.free(unsafe.Pointer(csid)) |
| | | C.wrap_fn_fire_recorder(h.ffmpeg, csid, C.long(id)) |
| | | } |
| | | |
| | | // BuildRecorder build recorder |
| | | func (h *GoFFMPEG) BuildRecorder(sid, output string, mind, maxd int, audio bool) { |
| | | out := C.CString(output) |
| | | defer C.free(unsafe.Pointer(out)) |
| | | csid := C.CString(sid) |
| | | defer C.free(unsafe.Pointer(csid)) |
| | | |
| | | a := 0 |
| | | if audio { |
| | | a = 1 |
| | | } |
| | | C.wrap_fn_recorder(h.ffmpeg, csid, out, C.int(mind), C.int(maxd), C.int(a)) |
| | | } |
| | | |
| | | // GetInfoRecorder info |
| | | func (h *GoFFMPEG) GetInfoRecorder() (string, int, string) { |
| | | var i C.int = -1 |
| | | |
| | | var id *C.char |
| | | var idl C.int |
| | | |
| | | var p *C.char |
| | | var pl C.int |
| | | |
| | | C.wrap_fn_info_recorder(h.ffmpeg, &i, &id, &idl, &p, &pl) |
| | | // if p == nil { |
| | | // return -1, "" |
| | | // } |
| | | gID := C.GoString(id) |
| | | C.free(unsafe.Pointer(id)) |
| | | path := C.GoString(p) |
| | | C.free(unsafe.Pointer(p)) |
| | | |
| | | // fmt.Println("Go get info : ", path, " len: ", l) |
| | | |
| | | return gID, int(i), path |
| | | } |
| | | |
| | | // BuildDecoder build decoder |
| | | func (h *GoFFMPEG) BuildDecoder() { |
| | | C.wrap_fn_decoder(h.ffmpeg) |
| | | } |
| | | |
| | | // GetPicDecoder get pic from decoder |
| | | func (h *GoFFMPEG) GetPicDecoder() ([]byte, int, int, int64) { |
| | | var width C.int |
| | | var height C.int |
| | | var fid C.long |
| | | |
| | | p := C.wrap_fn_decoder_pic(h.ffmpeg, &width, &height, &fid) |
| | | if width == 0 && height == 0 { |
| | | return nil, 0, 0, 0 |
| | | } |
| | | defer C.free(unsafe.Pointer(p)) |
| | | d := C.GoBytes(p, width*height*3) |
| | | wid := int(width) |
| | | hei := int(height) |
| | | gfid := int64(fid) |
| | | return d, wid, hei, gfid |
| | | } |
| | | |
| | | //GetAVPacket get AVPacket |
| | | func (h *GoFFMPEG) GetAVPacket() ([]byte, int, int) { |
| | | var key C.int |
| | | var size C.int |
| | | |
| | | p := C.wrap_fn_get_avpacket(h.ffmpeg, &size, &key) |
| | | if size <= 0 { |
| | | return nil, 0, -1 |
| | | } |
| | | defer C.free(unsafe.Pointer(p)) |
| | | d := C.GoBytes(p, size) |
| | | s := int(size) |
| | | k := int(key) |
| | | |
| | | return d, s, k |
| | | } |
| | | |
| | | /////////////// for decoder |
| | | |
| | | // Decode decode jpeg file |
| | | // return val: -1 open error; -2, find stream error; -3, converter create error |
| | | func Decode(input string, gb bool) ([]byte, int, int) { |
| | | in := C.CString(input) |
| | | defer C.free(unsafe.Pointer(in)) |
| | | |
| | | withGB := 0 |
| | | if gb { |
| | | withGB = 1 |
| | | } |
| | | |
| | | var width C.int |
| | | var height C.int |
| | | p := C.wrap_fn_decode(in, C.int(withGB), &width, &height) |
| | | defer C.free(p) |
| | | |
| | | if width > 0 && height > 0 { |
| | | data := C.GoBytes(p, width*height*3) |
| | | wid := int(width) |
| | | hei := int(height) |
| | | return data, wid, hei |
| | | } |
| | | return nil, int(width), int(height) |
| | | } |
| | | |
| | | ///////////////for encoder |
| | | |
| | | // GoEncoder encoder |
| | | type GoEncoder struct { |
| | | enc C.cencoder |
| | | } |
| | | |
| | | // NewEncoder encoder |
| | | func NewEncoder(w, h, fps, br, sFlag, gi int) *GoEncoder { |
| | | if w <= 0 || h <= 0 { |
| | | return nil |
| | | } |
| | | |
| | | return &GoEncoder{ |
| | | enc: C.wrap_fn_create_encoder(C.int(w), C.int(h), C.int(fps), C.int(br), C.int(sFlag), C.int(gi)), |
| | | } |
| | | } |
| | | |
| | | // Free free |
| | | func (e *GoEncoder) Free() { |
| | | C.wrap_fn_destroy_encoder(e.enc) |
| | | } |
| | | |
| | | // Encode pic |
| | | func (e *GoEncoder) Encode(in []byte, w, h int) ([]byte, int, bool) { |
| | | |
| | | var size C.int |
| | | var key C.int |
| | | cin := C.CBytes(in) |
| | | defer C.free(cin) |
| | | |
| | | p := C.wrap_fn_encode(e.enc, cin, C.int(w), C.int(h), &size, &key) |
| | | defer C.free(p) |
| | | if p != nil && size > 0 { |
| | | b := C.GoBytes(p, size) |
| | | |
| | | isKey := false |
| | | if key > 0 { |
| | | isKey = true |
| | | } |
| | | return b, int(size), isKey |
| | | } |
| | | return nil, 0, false |
| | | } |
New file |
| | |
| | | package goffmpeg |
| | | |
| | | /* |
| | | #include <stdlib.h> |
| | | #include "libcffmpeg.h" |
| | | */ |
| | | import "C" |
| | | |
| | | import "unsafe" |
| | | |
| | | /////////////// for decoder |
| | | |
| | | // Decode decode jpeg file |
| | | // return val: -1 open error; -2, find stream error; -3, converter create error |
| | | func Decode(input string, gb bool) ([]byte, int, int) { |
| | | in := C.CString(input) |
| | | defer C.free(unsafe.Pointer(in)) |
| | | |
| | | withGB := 0 |
| | | if gb { |
| | | withGB = 1 |
| | | } |
| | | |
| | | var width C.int |
| | | var height C.int |
| | | p := C.wrap_fn_decode(in, C.int(withGB), &width, &height) |
| | | defer C.free(p) |
| | | |
| | | if width > 0 && height > 0 { |
| | | data := C.GoBytes(p, width*height*3) |
| | | wid := int(width) |
| | | hei := int(height) |
| | | return data, wid, hei |
| | | } |
| | | return nil, int(width), int(height) |
| | | } |
New file |
| | |
| | | package goffmpeg |
| | | |
| | | /* |
| | | #include <stdlib.h> |
| | | #include "libcffmpeg.h" |
| | | */ |
| | | import "C" |
| | | |
| | | import "unsafe" |
| | | |
| | | // FireRecorder fire recorder |
| | | func (h *GoFFMPEG) FireRecorder(sid string, id int64) { |
| | | csid := C.CString(sid) |
| | | defer C.free(unsafe.Pointer(csid)) |
| | | C.wrap_fn_fire_recorder(h.ffmpeg, csid, C.long(id)) |
| | | } |
| | | |
| | | // BuildRecorder build recorder |
| | | func (h *GoFFMPEG) BuildRecorder(sid, output string, mind, maxd int, audio bool) { |
| | | out := C.CString(output) |
| | | defer C.free(unsafe.Pointer(out)) |
| | | csid := C.CString(sid) |
| | | defer C.free(unsafe.Pointer(csid)) |
| | | |
| | | a := 0 |
| | | if audio { |
| | | a = 1 |
| | | } |
| | | C.wrap_fn_recorder(h.ffmpeg, csid, out, C.int(mind), C.int(maxd), C.int(a)) |
| | | } |
| | | |
| | | // GetInfoRecorder info |
| | | func (h *GoFFMPEG) GetInfoRecorder() (string, int, string) { |
| | | var i C.int = -1 |
| | | |
| | | var id *C.char |
| | | var idl C.int |
| | | |
| | | var p *C.char |
| | | var pl C.int |
| | | |
| | | C.wrap_fn_info_recorder(h.ffmpeg, &i, &id, &idl, &p, &pl) |
| | | // if p == nil { |
| | | // return -1, "" |
| | | // } |
| | | gID := C.GoString(id) |
| | | C.free(unsafe.Pointer(id)) |
| | | path := C.GoString(p) |
| | | C.free(unsafe.Pointer(p)) |
| | | |
| | | // fmt.Println("Go get info : ", path, " len: ", l) |
| | | |
| | | return gID, int(i), path |
| | | } |
New file |
| | |
| | | package goffmpeg |
| | | |
| | | /* |
| | | #include <stdlib.h> |
| | | #include "libcffmpeg.h" |
| | | */ |
| | | import "C" |
| | | |
| | | import "unsafe" |
| | | |
| | | //GetAVPacket get AVPacket |
| | | func (h *GoFFMPEG) GetAVPacket() ([]byte, int, int) { |
| | | var key C.int |
| | | var size C.int |
| | | |
| | | p := C.wrap_fn_get_avpacket(h.ffmpeg, &size, &key) |
| | | if size <= 0 { |
| | | return nil, 0, -1 |
| | | } |
| | | defer C.free(unsafe.Pointer(p)) |
| | | d := C.GoBytes(p, size) |
| | | s := int(size) |
| | | k := int(key) |
| | | |
| | | return d, s, k |
| | | } |
| | |
| | | release_if_err(fn_destroy, lib); |
| | | fn_run = (lib_cffmpeg_run)dlsym(lib, "c_ffmpeg_run"); |
| | | release_if_err(fn_run, lib); |
| | | fn_scale = (lib_cffmpeg_scale)dlsym(lib, "c_ffmpeg_scale"); |
| | | release_if_err(fn_scale, lib); |
| | | fn_gb28181 = (lib_cffmpeg_gb28181)dlsym(lib, "c_ffmpeg_run_gb28181"); |
| | | release_if_err(fn_gb28181, lib); |
| | | fn_cpu = (lib_cffmpeg_cpu)dlsym(lib, "c_ffmepg_use_cpu"); |
| | |
| | | release_if_err(fn_destroy_encoder, lib); |
| | | fn_encode = (lib_cffmpeg_encode)dlsym(lib, "c_ffmpeg_encode"); |
| | | release_if_err(fn_encode, lib); |
| | | |
| | | fn_create_conv = (lib_cffmpeg_create_conv)dlsym(lib, "c_ffmpeg_create_conv"); |
| | | release_if_err(fn_create_conv, lib); |
| | | fn_destroy_conv = (lib_cffmpeg_destroy_conv)dlsym(lib, "c_ffmpeg_destroy_conv"); |
| | | release_if_err(fn_destroy_conv, lib); |
| | | fn_conv = (lib_cffmpeg_conv)dlsym(lib, "c_ffmpeg_conv"); |
| | | release_if_err(fn_conv, lib); |
| | | |
| | | fn_gpu_conv = (lib_gpu_conv)dlsym(lib, "c_gpu_conv"); |
| | | release_if_err(fn_gpu_conv, lib); |
| | | |
| | | }else{ |
| | | printf("dlopen - %s\n", dlerror()); |
| | |
| | | fn_run(h, input); |
| | | } |
| | | |
| | | void wrap_fn_scale(const cffmpeg h, const int wid, const int hei, const int flags){ |
| | | fn_scale(h, wid, hei, flags); |
| | | } |
| | | |
| | | void wrap_fn_run_gb28181(const cffmpeg h){ |
| | | fn_gb28181(h); |
| | | } |
| | |
| | | fn_decoder(h); |
| | | } |
| | | |
| | | void* wrap_fn_decoder_pic(const cffmpeg h, int* wid, int* hei, int64_t *id){ |
| | | return fn_decoder_pic(h, wid, hei, id); |
| | | void* wrap_fn_decoder_pic(const cffmpeg h, int *wid, int *hei, int *format, int *length, int64_t *id){ |
| | | return fn_decoder_pic(h, wid, hei, format, length, id); |
| | | } |
| | | |
| | | void* wrap_fn_get_avpacket(const cffmpeg h, int* size, int* key){ |
| | |
| | | // return val: -1 open error; -2, find stream error; -3, converter create error |
| | | void* wrap_fn_decode(const char* file, const int gb, int* wid, int* hei){ |
| | | return fn_decode(file, gb, wid, hei); |
| | | } |
| | | |
| | | void* wran_fn_gpu_conv(void *in, const int w, const int h, const int dst_w, const int dst_h, int *length){ |
| | | return fn_gpu_conv(in, w, h, dst_w, dst_h, length); |
| | | } |
| | | |
| | | // for encoder |
| | |
| | | *key = 0; |
| | | return NULL; |
| | | } |
| | | |
| | | // for conv |
| | | cconv wrap_fn_create_conv(const int srcW, const int srcH, const int srcFormat, |
| | | const int dstW, const int dstH, const int flag){ |
| | | return fn_create_conv(srcW, srcH, srcFormat, dstW, dstH, flag); |
| | | } |
| | | |
| | | void wrap_fn_destroy_conv(const cconv h){ |
| | | fn_destroy_conv(h); |
| | | } |
| | | void* wrap_fn_conv(const cconv h, uint8_t *in){ |
| | | return fn_conv(h, in); |
| | | } |
| | |
| | | typedef cffmpeg(*lib_cffmpeg_create2)(const char*); |
| | | typedef void (*lib_cffmpeg_destroy)(const cffmpeg); |
| | | typedef void (*lib_cffmpeg_run)(const cffmpeg, const char*); |
| | | typedef void (*lib_cffmpeg_scale)(const cffmpeg, const int, const int, const int); |
| | | typedef void (*lib_cffmpeg_gb28181)(const cffmpeg); |
| | | typedef void (*lib_cffmpeg_cpu)(const cffmpeg); |
| | | typedef void (*lib_cffmpeg_recorder)(const cffmpeg, const char*, const char*, int, int, int); |
| | | typedef void (*lib_cffmpeg_fire_recorder)(const cffmpeg, const char*, const int64_t); |
| | | typedef void (*lib_cffmpeg_info_recorder)(const cffmpeg, int*, char**, int*, char**, int*); |
| | | typedef void (*lib_cffmpeg_decoder)(const cffmpeg); |
| | | typedef void*(*lib_cffmpeg_pic)(const cffmpeg, int*, int*, int64_t*); |
| | | typedef void*(*lib_cffmpeg_pic)(const cffmpeg, int*, int*, int*, int*, int64_t*); |
| | | typedef void*(*lib_cffmpeg_avpacket)(const cffmpeg, int*, int*); |
| | | typedef void*(*lib_cffmpeg_decode)(const char*, const int, int*, int*); |
| | | typedef void*(*lib_gpu_conv)(void*, const int, const int, const int, const int, int *); |
| | | |
| | | static lib_cffmpeg_create fn_create = NULL; |
| | | static lib_cffmpeg_create2 fn_create2 = NULL; |
| | | static lib_cffmpeg_destroy fn_destroy = NULL; |
| | | static lib_cffmpeg_run fn_run = NULL; |
| | | static lib_cffmpeg_scale fn_scale = NULL; |
| | | static lib_cffmpeg_gb28181 fn_gb28181 = NULL; |
| | | static lib_cffmpeg_cpu fn_cpu = NULL; |
| | | static lib_cffmpeg_recorder fn_recorder = NULL; |
| | |
| | | static lib_cffmpeg_pic fn_decoder_pic = NULL; |
| | | static lib_cffmpeg_avpacket fn_get_avpacket = NULL; |
| | | static lib_cffmpeg_decode fn_decode = NULL; |
| | | static lib_gpu_conv fn_gpu_conv = NULL; |
| | | |
| | | typedef void* libcffmpeg; |
| | | libcffmpeg init_libcffmpeg(const char *so_file); |
| | |
| | | cffmpeg wrap_fn_create2(const char *logfile); |
| | | void wrap_fn_destroy(const cffmpeg h); |
| | | void wrap_fn_run(const cffmpeg h, const char* input); |
| | | void wrap_fn_scale(const cffmpeg h, const int wid, const int hei, const int flags); |
| | | void wrap_fn_run_gb28181(const cffmpeg h); |
| | | void wrap_fn_use_cpu(const cffmpeg h); |
| | | void wrap_fn_recorder(const cffmpeg h, const char* id, const char* dir, int mind, int maxd, int audio); |
| | | void wrap_fn_fire_recorder(const cffmpeg h, const char *sid, const int64_t id); |
| | | void wrap_fn_info_recorder(const cffmpeg, int* index, char** recid, int* recidLen, char** fpath, int* pathLen); |
| | | void wrap_fn_decoder(const cffmpeg h); |
| | | void* wrap_fn_decoder_pic(const cffmpeg h, int* wid, int* hei, int64_t *id); |
| | | void* wrap_fn_decoder_pic(const cffmpeg h, int *wid, int *hei, int *format, int *length, int64_t *id); |
| | | void* wrap_fn_get_avpacket(const cffmpeg h, int* size, int* key); |
| | | void* wrap_fn_decode(const char* file, const int gb, int* wid, int* hei); |
| | | |
| | | |
| | | void* wran_fn_gpu_conv(void *in, const int w, const int h, const int dst_w, const int dst_h, int *length); |
| | | // for encoder |
| | | typedef void* cencoder; |
| | | |
| | | typedef cencoder (*lib_cffmpeg_create_encoder)(const int w, const int h, const int fps, const int br, const int scale_flag, const int gi); |
| | | typedef void (*lib_cffmpeg_destroy_encoder)(cencoder h); |
| | | typedef int (*lib_cffmpeg_encode)(cencoder hdl, uint8_t *in, const int w, const int h, uint8_t **out, int *size, int *key); |
| | |
| | | void wrap_fn_destroy_encoder(const cencoder h); |
| | | void* wrap_fn_encode(cencoder hdl, void *in, const int w, const int h, int *out_size, int *key); |
| | | |
| | | |
| | | // for conv |
| | | typedef void *cconv; |
| | | typedef cconv (*lib_cffmpeg_create_conv)(const int, const int, const int, const int, const int, const int); |
| | | typedef void* (*lib_cffmpeg_conv)(const cconv, uint8_t *in); |
| | | typedef void (*lib_cffmpeg_destroy_conv)(const cconv); |
| | | |
| | | static lib_cffmpeg_create_conv fn_create_conv = NULL; |
| | | static lib_cffmpeg_destroy_conv fn_destroy_conv = NULL; |
| | | static lib_cffmpeg_conv fn_conv = NULL; |
| | | |
| | | cconv wrap_fn_create_conv(const int srcW, const int srcH, const int srcFormat, |
| | | const int dstW, const int dstH, const int flag); |
| | | void wrap_fn_destroy_conv(const cconv h); |
| | | void* wrap_fn_conv(const cconv h, uint8_t *in); |
| | | |
| | | #ifdef __cplusplus |
| | | } |
| | | #endif |