From 080acae08ec8cfe413c3e6e45bcf7f9222dfa02d Mon Sep 17 00:00:00 2001 From: zhangmeng <775834166@qq.com> Date: 星期四, 24 十月 2019 16:50:28 +0800 Subject: [PATCH] update --- csrc/worker/decoder.cpp | 122 ++++++++++++++++++++-------------------- 1 files changed, 60 insertions(+), 62 deletions(-) diff --git a/csrc/worker/decoder.cpp b/csrc/worker/decoder.cpp index 4cd1f8d..558d871 100644 --- a/csrc/worker/decoder.cpp +++ b/csrc/worker/decoder.cpp @@ -3,13 +3,14 @@ #include "../ffmpeg/bridge/cvbridge.hpp" #include "../ffmpeg/format/FormatIn.hpp" #include "../ffmpeg/data/CodedData.hpp" -#include "../ffmpeg/data/FrameData.hpp" #include "../ffmpeg/log/log.hpp" +#include "../common.hpp" extern "C"{ #include <libavformat/avformat.h> #include <libavutil/opt.h> #include <libswscale/swscale.h> +#include <libavcodec/avcodec.h> } using namespace ffwrapper; @@ -17,24 +18,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_pic_); - for(auto &i : list_pic_){ + std::lock_guard<std::mutex> l(mutex_frm_); + for(auto i : list_frm_){ free(i.data); } - list_pic_.clear(); + list_frm_.clear(); } int decoder::initDecoder(){ @@ -43,18 +37,7 @@ if(decRef_->getCodecContext() == NULL){ bool flag = true; - flag = decRef_->openCodec(AVMEDIA_TYPE_VIDEO, 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_); + flag = decRef_->openCodec(NULL); if (!flag){ logIt("FormatIn openCodec Failed!"); @@ -64,52 +47,67 @@ return 0; } - int decoder::SetFrame(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id){ - if (!data) return -1; - if (decRef_->isAudioPkt(data->getAVPacket())) return -2; + 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; + frm.data = cvbridge::extractFrame(frame, &frm.length); - if (!conv_){ - initDecoder(); - } - auto frame(std::make_shared<FrameData>()); - auto ret = decRef_->decode(frame, data); - if(ret == 1){ - //缂撳瓨鏁版嵁 - BGR24 pic; - AVFrame *frm = frame->getAVFrame(); - 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() > 10){ - for(int i = 0; i < 5; i++){ - auto t = list_pic_.front(); - free(t.data); - list_pic_.pop_front(); - } + 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(); } - list_pic_.emplace_back(pic); - } - return list_pic_.size(); + if (!frm.data) return 0; + list_frm_.push_back(frm); + return list_frm_.size(); } - 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()){ + int decoder::SetFrame(const CPacket &pkt){ + auto data = pkt.data; + + if (!data) return -10; + if (!decRef_->isVideoPkt(&data->getAVPacket())) return -20; + + if (decRef_->getCodecContext() == NULL){ + 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){ + 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){ + + std::lock_guard<std::mutex> l(mutex_frm_); + if(list_frm_.empty()){ *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; + auto p = list_frm_.front(); + list_frm_.pop_front(); + *data = p.data; *id = p.id; - list_pic_.pop_front(); + *w = p.width; + *h = p.height; + *format = p.format; + *length = p.length; } } // namespace cffmpeg_wrap -- Gitblit v1.8.0