From 68a19a73681301c6712e10d55bc64324716dbd24 Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期三, 09 十月 2019 15:38:47 +0800
Subject: [PATCH] split scale
---
gostream.go | 26 +
cffmpeg.h | 14
csrc/ffmpeg/configure/conf.cpp | 2
goenc.go | 54 +++
csrc/gpu-conv/CUDALERP.cu | 95 +++++
CMakeLists.txt | 8
csrc/gpu-conv/CUDALERP.h | 54 +++
csrc/wrapper.cpp | 118 ++++++
godec.go | 28 +
csrc/worker/decoder.cpp | 106 ++---
csrc/wrapper.hpp | 16
goffmpeg.go | 215 -----------
csrc/worker/decoder.hpp | 24
goconv.go | 100 +++++
libcffmpeg.c | 37 +
gojpeg.go | 36 ++
csrc/cffmpeg.cpp | 26 +
gorec.go | 54 +++
libcffmpeg.h | 29 +
19 files changed, 725 insertions(+), 317 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5ef89c8..6e1e6b5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,7 +22,12 @@
${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)
@@ -47,7 +52,8 @@
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)
diff --git a/cffmpeg.h b/cffmpeg.h
index c794216..ccc21a6 100644
--- a/cffmpeg.h
+++ b/cffmpeg.h
@@ -15,7 +15,6 @@
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
@@ -24,10 +23,10 @@
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
@@ -35,6 +34,15 @@
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
diff --git a/csrc/cffmpeg.cpp b/csrc/cffmpeg.cpp
index 7b31f3f..9ade6f9 100644
--- a/csrc/cffmpeg.cpp
+++ b/csrc/cffmpeg.cpp
@@ -33,11 +33,6 @@
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();
@@ -90,10 +85,10 @@
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;
}
@@ -121,3 +116,20 @@
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);
+}
\ No newline at end of file
diff --git a/csrc/ffmpeg/configure/conf.cpp b/csrc/ffmpeg/configure/conf.cpp
index d836840..43e45ac 100644
--- a/csrc/ffmpeg/configure/conf.cpp
+++ b/csrc/ffmpeg/configure/conf.cpp
@@ -13,7 +13,7 @@
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){
diff --git a/csrc/gpu-conv/CUDALERP.cu b/csrc/gpu-conv/CUDALERP.cu
new file mode 100644
index 0000000..ee44fee
--- /dev/null
+++ b/csrc/gpu-conv/CUDALERP.cu
@@ -0,0 +1,95 @@
+/*******************************************************************
+* 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();
+}
diff --git a/csrc/gpu-conv/CUDALERP.h b/csrc/gpu-conv/CUDALERP.h
new file mode 100644
index 0000000..1645cb9
--- /dev/null
+++ b/csrc/gpu-conv/CUDALERP.h
@@ -0,0 +1,54 @@
+/*******************************************************************
+* 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);
diff --git a/csrc/worker/decoder.cpp b/csrc/worker/decoder.cpp
index ce5f631..67af0a1 100644
--- a/csrc/worker/decoder.cpp
+++ b/csrc/worker/decoder.cpp
@@ -17,27 +17,17 @@
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(){
@@ -47,17 +37,6 @@
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!");
@@ -68,25 +47,15 @@
}
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){
@@ -94,7 +63,7 @@
if (!data) return -1;
if (!decRef_->isVideoPkt(&data->getAVPacket())) return -2;
- if (!conv_){
+ if (decRef_->getCodecContext() == NULL){
if (initDecoder() != 0) return -3;
}
@@ -107,21 +76,50 @@
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
diff --git a/csrc/worker/decoder.hpp b/csrc/worker/decoder.hpp
index ae9fba2..94bbb03 100644
--- a/csrc/worker/decoder.hpp
+++ b/csrc/worker/decoder.hpp
@@ -10,44 +10,40 @@
#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();
};
diff --git a/csrc/wrapper.cpp b/csrc/wrapper.cpp
index c03b54f..2643ce0 100644
--- a/csrc/wrapper.cpp
+++ b/csrc/wrapper.cpp
@@ -24,6 +24,8 @@
#include "worker/decoder.hpp"
#include "worker/rec.hpp"
+#include "CUDALERP.h"
+
using namespace logif;
using namespace ffwrapper;
@@ -40,9 +42,6 @@
Wrapper::Wrapper()
:input_url_("")
- ,scale_w_(0)
- ,scale_h_(0)
- ,scale_f_(SWS_POINT)
,audio_(false)
,gb_(0)
,cpu_(0)
@@ -59,9 +58,6 @@
Wrapper::Wrapper(const char *logfile)
:input_url_("")
- ,scale_w_(0)
- ,scale_h_(0)
- ,scale_f_(SWS_POINT)
,audio_(false)
,gb_(0)
,cpu_(0)
@@ -154,7 +150,7 @@
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_) {
@@ -253,9 +249,9 @@
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);
}
}
@@ -427,5 +423,109 @@
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);
+ }
}
diff --git a/csrc/wrapper.hpp b/csrc/wrapper.hpp
index af976e5..13d5f7d 100644
--- a/csrc/wrapper.hpp
+++ b/csrc/wrapper.hpp
@@ -44,23 +44,18 @@
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_;
@@ -80,10 +75,17 @@
};
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
\ No newline at end of file
diff --git a/goconv.go b/goconv.go
new file mode 100644
index 0000000..459b3dd
--- /dev/null
+++ b/goconv.go
@@ -0,0 +1,100 @@
+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
+
+}
diff --git a/godec.go b/godec.go
new file mode 100644
index 0000000..a232618
--- /dev/null
+++ b/godec.go
@@ -0,0 +1,28 @@
+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)
+}
diff --git a/goenc.go b/goenc.go
new file mode 100644
index 0000000..3d00996
--- /dev/null
+++ b/goenc.go
@@ -0,0 +1,54 @@
+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
+}
diff --git a/goffmpeg.go b/goffmpeg.go
index d23bf80..dedb2bf 100644
--- a/goffmpeg.go
+++ b/goffmpeg.go
@@ -12,31 +12,6 @@
"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
@@ -59,35 +34,23 @@
}
}
-// 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)
}
@@ -97,21 +60,18 @@
}
// 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)
}
@@ -122,7 +82,9 @@
// 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
@@ -131,161 +93,4 @@
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
}
diff --git a/gojpeg.go b/gojpeg.go
new file mode 100644
index 0000000..6cc855d
--- /dev/null
+++ b/gojpeg.go
@@ -0,0 +1,36 @@
+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)
+}
diff --git a/gorec.go b/gorec.go
new file mode 100644
index 0000000..dcf0f5e
--- /dev/null
+++ b/gorec.go
@@ -0,0 +1,54 @@
+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
+}
diff --git a/gostream.go b/gostream.go
new file mode 100644
index 0000000..6345ebd
--- /dev/null
+++ b/gostream.go
@@ -0,0 +1,26 @@
+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
+}
diff --git a/libcffmpeg.c b/libcffmpeg.c
index 69fcbb9..2414a16 100644
--- a/libcffmpeg.c
+++ b/libcffmpeg.c
@@ -25,8 +25,6 @@
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");
@@ -52,6 +50,16 @@
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());
@@ -81,10 +89,6 @@
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);
}
@@ -109,8 +113,8 @@
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){
@@ -120,6 +124,10 @@
// 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
@@ -141,3 +149,16 @@
*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);
+}
diff --git a/libcffmpeg.h b/libcffmpeg.h
index 5b43da3..44d82b2 100644
--- a/libcffmpeg.h
+++ b/libcffmpeg.h
@@ -14,22 +14,21 @@
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;
@@ -39,6 +38,7 @@
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);
@@ -48,21 +48,18 @@
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);
@@ -75,6 +72,22 @@
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
--
Gitblit v1.8.0