From 1939b7042d568c50509118a6031829ee5bf5f544 Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期五, 29 十一月 2019 13:23:15 +0800
Subject: [PATCH] lower cpu and mem
---
csrc/worker/decoder.cpp | 110 ++++++++++++++++++------------------
csrc/worker/decoder.hpp | 18 +----
2 files changed, 60 insertions(+), 68 deletions(-)
diff --git a/csrc/worker/decoder.cpp b/csrc/worker/decoder.cpp
index 4d432c1..a57cf0e 100644
--- a/csrc/worker/decoder.cpp
+++ b/csrc/worker/decoder.cpp
@@ -20,16 +20,13 @@
{
decoder::decoder(ffwrapper::FormatIn *dec)
:decRef_(dec)
+ ,next_idx_(-1)
{}
decoder::~decoder(){
- std::lock_guard<std::mutex> l(mutex_frm_);
- for(auto i : list_frm_){
- if (i.avframe)
- av_frame_free(&i.avframe);
- }
- list_frm_.clear();
+ std::lock_guard<std::mutex> l(mutex_pkt_);
+ list_pkt_.clear();
}
int decoder::initDecoder(){
@@ -58,46 +55,71 @@
if (initDecoder() != 0) return -30;
}
- AVFrame *frame = av_frame_alloc();
- AVPacket np(data->getAVPacket());
- av_copy_packet(&np, &data->getAVPacket());
- auto ret = decRef_->decode(frame, &np);
- av_packet_unref(&np);
-
- if (ret == 0){
- return saveFrame(frame, pkt.v_id);
+ std::lock_guard<std::mutex> l(mutex_pkt_);
+ if (data->getAVPacket().flags & AV_PKT_FLAG_KEY){
+ logIt("new list cpacket start, next %lld, cur %lld", next_idx_, pkt.id);
+ list_pkt_.clear();
}
+ list_pkt_.push_back(pkt);
- return ret;
+ return list_pkt_.size();
}
void decoder::GetFrame(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){
- FRM frm;
+
+ AVFrame *frame = NULL;
+
{
- std::lock_guard<std::mutex> l(mutex_frm_);
- if(list_frm_.empty()){
- return;
+ std::lock_guard<std::mutex> l(mutex_pkt_);
+ if (list_pkt_.empty()) return;
+ auto check = list_pkt_.front();
+ if (check.id > next_idx_){
+ next_idx_ = -1;
+ logIt("decoder new list cpacket");
}
- frm = list_frm_.front();
- list_frm_.pop_front();
+
+ for (auto &i : list_pkt_){
+ if (i.id < next_idx_){
+ continue;
+ logIt("decoder same list cpacket");
+ }
+
+ *id = i.v_id;
+ auto data = i.data;
+
+ AVFrame *frm = av_frame_alloc();
+ AVPacket np(data->getAVPacket());
+ av_copy_packet(&np, &data->getAVPacket());
+ auto ret = decRef_->decode(frm, &np);
+ av_packet_unref(&np);
+ if (ret == 0){
+ next_idx_ = i.id + 1;
+ if (frame) {av_frame_free(&frame); frame = NULL;}
+ frame = frm;
+ }
+ }
}
-
- AVFrame *frame = frm.avframe;
+ if (!frame) return;
+
int pix_fmt = frame->format;
- uint8_t *origin = cvbridge::extractFrame(frame, &frm.length);
+ int width = frame->width;
+ int height = frame->height;
+ int len = 0;
+
+ uint8_t *origin = cvbridge::extractFrame(frame, &len);
av_frame_free(&frame);
if (!origin) return;
uint8_t *finale = NULL;
if (pix_fmt != AV_PIX_FMT_NV12){
- finale = (uint8_t*)malloc(frm.length);
+ finale = (uint8_t*)malloc(len);
- 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);
+ unsigned char* SrcU = origin + width * height;
+ unsigned char* SrcV = SrcU + width * height / 4 ;
+ unsigned char* DstU = finale + width * height;
+ memcpy(finale, origin, width * height);
int i = 0;
- for( i = 0 ; i < frm.width * frm.height / 4 ; i++ ){
+ for( i = 0 ; i < width * height / 4 ; i++ ){
*(DstU++) = *(SrcU++);
*(DstU++) = *(SrcV++);
}
@@ -107,32 +129,10 @@
}
*data = finale;
- *id = frm.id;
- *w = frm.width;
- *h = frm.height;
+ *w = width;
+ *h = 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_);
- 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();
- }
- }
-
- list_frm_.push_back(frm);
- return list_frm_.size();
+ *length = len;
}
} // namespace cffmpeg_wrap
diff --git a/csrc/worker/decoder.hpp b/csrc/worker/decoder.hpp
index 533140d..7f87180 100644
--- a/csrc/worker/decoder.hpp
+++ b/csrc/worker/decoder.hpp
@@ -22,32 +22,24 @@
namespace cffmpeg_wrap
{
- typedef struct _frm{
- AVFrame *avframe;
- int length;
- int width;
- int height;
- int64_t id;
- }FRM;
-
class decoder
{
private:
ffwrapper::FormatIn *decRef_;
- std::list<FRM> list_frm_;
- std::mutex mutex_frm_;
+ std::list<CPacket> list_pkt_;
+ std::mutex mutex_pkt_;
+ int64_t next_idx_;
+
private:
int initDecoder();
- int saveFrame(AVFrame *frame, const int64_t &id);
public:
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();
--
Gitblit v1.8.0