From fa8b072f4c5359703ae664ef8a5d79139742e2e8 Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期五, 29 十一月 2019 11:20:08 +0800
Subject: [PATCH] optimize ffmpeg decode cpu and memory
---
csrc/worker/rec.cpp | 2
csrc/worker/decoder.cpp | 121 +++++++++++++++++++++-------------------
csrc/worker/decoder.hpp | 6 +-
3 files changed, 67 insertions(+), 62 deletions(-)
diff --git a/csrc/worker/decoder.cpp b/csrc/worker/decoder.cpp
index f96f864..4d432c1 100644
--- a/csrc/worker/decoder.cpp
+++ b/csrc/worker/decoder.cpp
@@ -26,7 +26,8 @@
std::lock_guard<std::mutex> l(mutex_frm_);
for(auto i : list_frm_){
- free(i.data);
+ if (i.avframe)
+ av_frame_free(&i.avframe);
}
list_frm_.clear();
}
@@ -47,47 +48,6 @@
return 0;
}
- int decoder::saveFrame(AVFrame *frame, const int64_t &id){
- FRM frm;
- frm.width = frame->width;
- frm.height = frame->height;
- frm.format = frame->format;
- frm.id = id;
- uint8_t *origin = cvbridge::extractFrame(frame, &frm.length);
- if (!origin) return -1;
-
- uint8_t *finale = NULL;
- if (frame->format != AV_PIX_FMT_NV12){
- finale = (uint8_t*)malloc(frm.length);
-
- unsigned char* SrcU = origin + frm.width * frm.height;
- unsigned char* SrcV = SrcU + frm.width * frm.height / 4 ;
- unsigned char* DstU = finale + frm.width * frm.height;
- memcpy(finale, origin, frm.width * frm.height);
- int i = 0;
- for( i = 0 ; i < frm.width * frm.height / 4 ; i++ ){
- *(DstU++) = *(SrcU++);
- *(DstU++) = *(SrcV++);
- }
- free(origin);
- }else{
- finale = origin;
- }
- frm.data = finale;
-
- std::lock_guard<std::mutex> l(mutex_frm_);
- while(list_frm_.size() > 50){
- for(int i = 0; i < 12; i++){
- auto t = list_frm_.front();
- free(t.data);
- list_frm_.pop_front();
- }
- }
- if (!frm.data) return 0;
- list_frm_.push_back(frm);
- return list_frm_.size();
- }
-
int decoder::SetFrame(const CPacket &pkt){
auto data = pkt.data;
@@ -103,31 +63,76 @@
av_copy_packet(&np, &data->getAVPacket());
auto ret = decRef_->decode(frame, &np);
av_packet_unref(&np);
-
+
if (ret == 0){
- saveFrame(frame, pkt.v_id);
+ return saveFrame(frame, pkt.v_id);
}
- av_frame_free(&frame);
+
return ret;
}
void decoder::GetFrame(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){
+ FRM frm;
+ {
+ std::lock_guard<std::mutex> l(mutex_frm_);
+ if(list_frm_.empty()){
+ return;
+ }
+ frm = list_frm_.front();
+ list_frm_.pop_front();
+ }
+
+ AVFrame *frame = frm.avframe;
+ int pix_fmt = frame->format;
+ uint8_t *origin = cvbridge::extractFrame(frame, &frm.length);
+ av_frame_free(&frame);
+ if (!origin) return;
+
+ uint8_t *finale = NULL;
+ if (pix_fmt != AV_PIX_FMT_NV12){
+ finale = (uint8_t*)malloc(frm.length);
+
+ unsigned char* SrcU = origin + frm.width * frm.height;
+ unsigned char* SrcV = SrcU + frm.width * frm.height / 4 ;
+ unsigned char* DstU = finale + frm.width * frm.height;
+ memcpy(finale, origin, frm.width * frm.height);
+ int i = 0;
+ for( i = 0 ; i < frm.width * frm.height / 4 ; i++ ){
+ *(DstU++) = *(SrcU++);
+ *(DstU++) = *(SrcV++);
+ }
+ free(origin);
+ }else{
+ finale = origin;
+ }
+
+ *data = finale;
+ *id = frm.id;
+ *w = frm.width;
+ *h = frm.height;
+ *format = pix_fmt;
+ *length = frm.length;
+ }
+////////////////////////////////////////////////////////////////////////
+static const int maxSize = 5;
+ int decoder::saveFrame(AVFrame *frame, const int64_t &id){
+ FRM frm;
+ frm.avframe = frame;
+ frm.width = frame->width;
+ frm.height = frame->height;
+ frm.id = id;
std::lock_guard<std::mutex> l(mutex_frm_);
- if(list_frm_.empty()){
- *data = NULL;
- *w = *h = 0;
- *id = -1;
- return;
+ while(list_frm_.size() > maxSize){
+ for(int i = 0; i < (maxSize>1); i++){
+ auto t = list_frm_.front();
+ av_frame_free(&t.avframe);
+ list_frm_.pop_front();
+ }
}
- auto p = list_frm_.front();
- list_frm_.pop_front();
- *data = p.data;
- *id = p.id;
- *w = p.width;
- *h = p.height;
- *format = p.format;
- *length = p.length;
+
+ list_frm_.push_back(frm);
+ return list_frm_.size();
}
} // namespace cffmpeg_wrap
diff --git a/csrc/worker/decoder.hpp b/csrc/worker/decoder.hpp
index 83a0293..533140d 100644
--- a/csrc/worker/decoder.hpp
+++ b/csrc/worker/decoder.hpp
@@ -23,11 +23,10 @@
namespace cffmpeg_wrap
{
typedef struct _frm{
- uint8_t *data;
+ AVFrame *avframe;
int length;
int width;
int height;
- int format;
int64_t id;
}FRM;
@@ -47,7 +46,8 @@
void Start();
int SetFrame(const CPacket &pkt);
void GetFrame(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id);
-
+ private:
+
public:
explicit decoder(ffwrapper::FormatIn *dec);
~decoder();
diff --git a/csrc/worker/rec.cpp b/csrc/worker/rec.cpp
index 9cecfb0..9a306b2 100644
--- a/csrc/worker/rec.cpp
+++ b/csrc/worker/rec.cpp
@@ -16,7 +16,7 @@
using namespace ffwrapper;
using namespace cffmpeg_wrap::buz;
-static const int cache_time = 6 * 60;
+static const int cache_time = 3 * 60 + 30;
namespace cffmpeg_wrap
{
--
Gitblit v1.8.0