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/decoder.cpp | 121 +++++++++++++++++++++------------------- 1 files changed, 63 insertions(+), 58 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 -- Gitblit v1.8.0