#include "decoder.hpp" #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" extern "C"{ #include #include #include } using namespace ffwrapper; using namespace logif; 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(){ if (conv_){ delete conv_; } std::lock_guard l(mutex_pic_); for(auto &i : list_pic_){ free(i.data); } list_pic_.clear(); } int decoder::initDecoder(){ if (!decRef_) return -1; 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_); if (!flag){ logIt("FormatIn openCodec Failed!"); return -1; } } return 0; } int decoder::SetFrame(std::shared_ptr data, int64_t &id){ if (!data) return -1; if (!conv_){ initDecoder(); } auto frame(std::make_shared()); 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 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(); } } list_pic_.emplace_back(pic); } return list_pic_.size(); } void decoder::GetFrame(unsigned char **data, int *w, int *h, int64_t *id){ std::lock_guard l(mutex_pic_); if(list_pic_.empty()){ *data = NULL; *w = 0; *h = 0; return; } auto p = list_pic_.front(); *data = p.data; *w = p.w; *h = p.h; *id = p.id; list_pic_.pop_front(); } } // namespace cffmpeg_wrap