From 93f44a10e2e8942e57e62bb210a2ca7d206a51b7 Mon Sep 17 00:00:00 2001 From: zhangmeng <775834166@qq.com> Date: 星期二, 24 九月 2019 11:26:44 +0800 Subject: [PATCH] add rec audio; --- csrc/worker/decoder.cpp | 140 +++++++++++++++++++++++++++++++++++----------- 1 files changed, 106 insertions(+), 34 deletions(-) diff --git a/csrc/worker/decoder.cpp b/csrc/worker/decoder.cpp index 4cd1f8d..4211b41 100644 --- a/csrc/worker/decoder.cpp +++ b/csrc/worker/decoder.cpp @@ -10,6 +10,7 @@ #include <libavformat/avformat.h> #include <libavutil/opt.h> #include <libswscale/swscale.h> +#include <libavcodec/avcodec.h> } using namespace ffwrapper; @@ -23,18 +24,33 @@ ,conv_h_(h) ,conv_flag_(f) ,decRef_(dec) + ,thread_(nullptr) + ,stop_{false} {} decoder::~decoder(){ + if (thread_){ + stop_.store(true); + thread_->join(); + } + if (conv_){ delete conv_; } - std::lock_guard<std::mutex> l(mutex_pic_); - for(auto &i : list_pic_){ - free(i.data); + + { + std::lock_guard<std::mutex> l(mutex_pkt_); + list_pkt_.clear(); } - list_pic_.clear(); + + { + std::lock_guard<std::mutex> l(mutex_pic_); + for(auto &i : list_pic_){ + free(i.data); + } + list_pic_.clear(); + } } int decoder::initDecoder(){ @@ -43,7 +59,7 @@ if(decRef_->getCodecContext() == NULL){ bool flag = true; - flag = decRef_->openCodec(AVMEDIA_TYPE_VIDEO, NULL); + flag = decRef_->openCodec(NULL); auto dec_ctx = decRef_->getCodecContext(); if(conv_){ delete conv_; @@ -64,40 +80,96 @@ 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; - - 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(); - } + 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(); } - list_pic_.emplace_back(pic); - } + list_pic_.emplace_back(pic); return list_pic_.size(); } + void decoder::Start(){ + if (thread_) return; + thread_.reset(new std::thread([&]{ + if (initDecoder() != 0) { + return; + } + + while(!stop_.load()){ + + std::unique_lock<std::mutex> locker(mutex_pkt_); + cv_.wait(locker, [&]{ + return !list_pkt_.empty() || stop_.load(); + }); + if (stop_.load()){ + break; + } + + auto pkt = list_pkt_.front(); + list_pkt_.pop_front(); + + AVFrame *frame = av_frame_alloc(); + AVPacket np(pkt.data->getAVPacket()); + av_copy_packet(&np, &pkt.data->getAVPacket()); + + auto ret = decRef_->decode(frame, &np); + av_packet_unref(&np); + + if (ret == 0){ + saveFrame(frame, pkt.id); + } + av_frame_free(&frame); + } + + })); + } + + int decoder::SetFrame(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id){ + + if (!data) return -1; + if (decRef_->isAudioPkt(&data->getAVPacket())) return -2; + + // if (!thread_){ + // if (initDecoder() != 0) return -3; + // Start(); + // } + + // 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; + } + + 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); + } + 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()){ -- Gitblit v1.8.0