From 18a05d269516a5e33d8460291c2f93e73d95adce Mon Sep 17 00:00:00 2001 From: zhangmeng <775834166@qq.com> Date: 星期二, 26 十二月 2023 10:45:31 +0800 Subject: [PATCH] GetYUV format is NV12 --- csrc/worker/decoder.cpp | 203 +++++++++++++++++++------------------------------- 1 files changed, 79 insertions(+), 124 deletions(-) diff --git a/csrc/worker/decoder.cpp b/csrc/worker/decoder.cpp index 4211b41..4d5a3b7 100644 --- a/csrc/worker/decoder.cpp +++ b/csrc/worker/decoder.cpp @@ -3,8 +3,8 @@ #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> @@ -18,39 +18,15 @@ 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) - ,thread_(nullptr) - ,stop_{false} + decoder::decoder(ffwrapper::FormatIn *dec) + :decRef_(dec) + ,next_idx_(-1) {} decoder::~decoder(){ - if (thread_){ - stop_.store(true); - thread_->join(); - } - - if (conv_){ - delete conv_; - } - - { - std::lock_guard<std::mutex> l(mutex_pkt_); - list_pkt_.clear(); - } - - { - std::lock_guard<std::mutex> l(mutex_pic_); - for(auto &i : list_pic_){ - free(i.data); - } - list_pic_.clear(); - } + std::lock_guard<std::mutex> l(mutex_pkt_); + list_pkt_.clear(); } int decoder::initDecoder(){ @@ -60,17 +36,6 @@ bool flag = true; flag = decRef_->openCodec(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!"); @@ -80,108 +45,98 @@ return 0; } - int decoder::saveFrame(AVFrame *frame, int64_t &id){ - //缂撳瓨鏁版嵁 - BGR24 pic; - AVFrame *frm = frame; - 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() > 50){ - for(int i = 0; i < 12; i++){ - auto t = list_pic_.front(); - free(t.data); - list_pic_.pop_front(); - } + 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; } - list_pic_.emplace_back(pic); - return list_pic_.size(); + + std::lock_guard<std::mutex> l(mutex_pkt_); + if (data->getAVPacket().flags & AV_PKT_FLAG_KEY){ + list_pkt_.clear(); + } + list_pkt_.push_back(pkt); + + return list_pkt_.size(); } - void decoder::Start(){ - if (thread_) return; - thread_.reset(new std::thread([&]{ - if (initDecoder() != 0) { - return; + void decoder::GetFrame(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){ + *data = NULL; + *length = 0; + + AVFrame *frame = NULL; + + { + 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; } - - while(!stop_.load()){ - - std::unique_lock<std::mutex> locker(mutex_pkt_); - cv_.wait(locker, [&]{ - return !list_pkt_.empty() || stop_.load(); - }); - if (stop_.load()){ - break; + + for (auto &i : list_pkt_){ + if (i.id < next_idx_){ + continue; } - auto pkt = list_pkt_.front(); - list_pkt_.pop_front(); + *id = i.v_id; + auto data = i.data; - AVFrame *frame = av_frame_alloc(); - AVPacket np(pkt.data->getAVPacket()); - av_copy_packet(&np, &pkt.data->getAVPacket()); - - auto ret = decRef_->decode(frame, &np); + 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){ - saveFrame(frame, pkt.id); + next_idx_ = i.id + 1; + if (frame) {av_frame_free(&frame); frame = NULL;} + frame = frm; + }else { + av_frame_free(&frm); } - av_frame_free(&frame); } + } + if (!frame) return; - })); - } + int pix_fmt = frame->format; + int width = frame->width; + int height = frame->height; - int decoder::SetFrame(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id){ + if (pix_fmt != AV_PIX_FMT_NV12){ - if (!data) return -1; - if (decRef_->isAudioPkt(&data->getAVPacket())) return -2; - - // if (!thread_){ - // if (initDecoder() != 0) return -3; - // Start(); - // } + cvbridge* bridge = new cvbridge(width, height, pix_fmt, + width, height, AV_PIX_FMT_NV12); + AVFrame* nv12 = bridge->convert2Frame(frame); + av_frame_free(&frame); + frame = nv12; + delete bridge; - // std::lock_guard<std::mutex> l(mutex_pkt_); - // list_pkt_.push_back({data, id}); - // cv_.notify_one(); - // return list_pkt_.size(); - - if (!conv_){ - if (initDecoder() != 0) return -3; + // finale = (uint8_t*)malloc(len); + // 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 < width * height / 4 ; i++ ){ + // *(DstU++) = *(SrcU++); + // *(DstU++) = *(SrcV++); + // } + // free(origin); } - 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, id); - } + int len = 0; + uint8_t* finale = cvbridge::extractFrame(frame, &len); av_frame_free(&frame); - } - - 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()){ - *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(); + *data = finale; + *w = width; + *h = height; + *format = pix_fmt; + *length = len; } } // namespace cffmpeg_wrap -- Gitblit v1.8.0