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 +++++++++++++++++++++++++++--------------------------- 1 files changed, 55 insertions(+), 55 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 -- Gitblit v1.8.0