From be9c1d1f659b0ff31f656424c478e83a4f7c53b5 Mon Sep 17 00:00:00 2001 From: zhangmeng <775834166@qq.com> Date: 星期五, 20 九月 2019 11:44:19 +0800 Subject: [PATCH] update ffmpeg --- cffmpeg.h | 2 csrc/buz/recorder.hpp | 6 csrc/buz/recorder.cpp | 28 +++ csrc/ffmpeg/format/FormatIn.hpp | 12 + csrc/ffmpeg/format/FormatIn.cpp | 83 +++++++---- csrc/ffmpeg/format/FormatOut.hpp | 10 + csrc/wrapper.cpp | 40 ++--- csrc/worker/rec.cpp | 8 csrc/worker/stream.cpp | 14 + csrc/worker/decoder.cpp | 1 csrc/wrapper.hpp | 17 + csrc/ffmpeg/format/FormatOut.cpp | 144 +++++++++++++++----- goffmpeg.go | 4 csrc/worker/rec.hpp | 4 csrc/worker/stream.hpp | 6 libcffmpeg.c | 4 csrc/cffmpeg.cpp | 6 libcffmpeg.h | 4 18 files changed, 268 insertions(+), 125 deletions(-) diff --git a/cffmpeg.h b/cffmpeg.h index cad8cb7..a1d1473 100644 --- a/cffmpeg.h +++ b/cffmpeg.h @@ -17,7 +17,7 @@ void c_ffmpeg_run_gb28181(const cffmpeg h); void c_ffmepg_use_cpu(const cffmpeg h); /////////passive api -void c_ffmpeg_build_recorder(const cffmpeg h, const char*id, const char *dir, int mind, int maxd); +void c_ffmpeg_build_recorder(const cffmpeg h, const char*id, const char *dir, int mind, int maxd, int audio); void c_ffmpeg_fire_recorder(const cffmpeg h, const char*sid, const int64_t id); void c_ffmpeg_get_info_recorder(const cffmpeg h, int *index, char** recid, int *recidLen, char **fpath, int *pathLen); diff --git a/csrc/buz/recorder.cpp b/csrc/buz/recorder.cpp index af5a1fc..86afe89 100644 --- a/csrc/buz/recorder.cpp +++ b/csrc/buz/recorder.cpp @@ -34,6 +34,7 @@ ,func_rec_info_(nullptr) ,thrd_(nullptr) ,error_occured_(false) + ,audio_(false) { // logIt("RECODER ID: %s", id_.c_str()); } @@ -59,7 +60,7 @@ } - int Recorder::init_writer(){ + int Recorder::init_writer(const bool audio){ if (out_) { delete out_; } @@ -69,10 +70,18 @@ return -1; } - out_ = new FormatOut(in_->getStream(), "mp4"); + out_ = new FormatOut(in_->getFPS(), "mp4"); + AVStream *vs = in_->getStream(0); + AVStream *as = in_->getStream(1); + if (!vs) return -1; + if (audio && !as) logIt("there is no audio"); + + std::vector<AVStream*> in; + in.push_back(vs); + if (audio && as) in.push_back(as); file_path_ = dir_ + "/" + sole::uuid4().base62() + ".mp4"; - auto ret = out_->JustWriter(in_->getStream(), file_path_.c_str()); + auto ret = out_->JustWriter(in, file_path_.c_str()); if (ret){ return 0; } @@ -162,10 +171,10 @@ end_writer(); } - int Recorder::Run(const char* output, const int mind, const int maxd){ + int Recorder::Run(const char* output, const int mind, const int maxd, const bool audio){ dir_ = output; - int ret = init_writer(); + int ret = init_writer(audio); if(ret != 0){ logIt("recorder init writer error"); return -1; @@ -177,6 +186,8 @@ minduration = fps * mind; end_frame = minduration; } + + audio_ = audio; // logIt("minduration %d maxduration %d curduration %d", minduration, maxduration, end_frame); @@ -221,6 +232,10 @@ if(id_frame_ == -1){ //wait I + if (!audio_ && in_->isAudioPkt(pkt.data->getAVPacket())){ + return 0; + } + if (list_pkt_.empty()) { AVPacket &avpkt = pkt.data->getAVPacket(); if (!(avpkt.flags & AV_PKT_FLAG_KEY)){ @@ -249,6 +264,9 @@ bool i = false; for (auto &p : lst){ if (!i){ + if (!audio_ && in_->isAudioPkt(p.data->getAVPacket())){ + continue; + } AVPacket &avpkt = p.data->getAVPacket(); if (!(avpkt.flags & AV_PKT_FLAG_KEY)){ continue; diff --git a/csrc/buz/recorder.hpp b/csrc/buz/recorder.hpp index 8c3b550..f044907 100644 --- a/csrc/buz/recorder.hpp +++ b/csrc/buz/recorder.hpp @@ -35,7 +35,7 @@ ~Recorder(); public: - int Run(const char* output, const int mind, const int maxd); + int Run(const char* output, const int mind, const int maxd, const bool audio); int PushPacket(const CPacket &pkt); int PushPackets(std::list<CPacket> &lst); int FireRecorder(const int64_t &id); @@ -49,7 +49,7 @@ private: void run_thread(); - int init_writer(); + int init_writer(const bool audio); int write_correctly(const CPacket &pkt); void end_writer(); @@ -80,6 +80,8 @@ FUNC_REC_INFO func_rec_info_; bool error_occured_; + + bool audio_; }; } } diff --git a/csrc/cffmpeg.cpp b/csrc/cffmpeg.cpp index 3a97159..eea69f8 100644 --- a/csrc/cffmpeg.cpp +++ b/csrc/cffmpeg.cpp @@ -48,9 +48,11 @@ //////passive api -void c_ffmpeg_build_recorder(const cffmpeg h, const char* id, const char *dir, int mind, int maxd){ +void c_ffmpeg_build_recorder(const cffmpeg h, const char* id, const char *dir, int mind, int maxd, int audio){ Wrapper *s = (Wrapper*)h; - s->BuildRecorder(id, dir, mind, maxd); + + bool a = audio == 0 ? false : true; + s->BuildRecorder(id, dir, mind, maxd, a); } void c_ffmpeg_fire_recorder(const cffmpeg h, const char* sid, const int64_t id){ diff --git a/csrc/ffmpeg/format/FormatIn.cpp b/csrc/ffmpeg/format/FormatIn.cpp index 3e9dd51..3f87d59 100644 --- a/csrc/ffmpeg/format/FormatIn.cpp +++ b/csrc/ffmpeg/format/FormatIn.cpp @@ -29,11 +29,13 @@ :ctx_(NULL) ,dec_ctx_(NULL) ,vs_idx_(-1) + ,as_idx_(-1) ,hw_accl_(hw) ,io_ctx_(NULL) ,read_io_buff_(NULL) ,read_io_buff_size_(32768) ,handle_gb28181(NULL) + ,fps_(25.0) {} FormatIn::~FormatIn() @@ -100,7 +102,7 @@ handle_gb28181 = new GB28181API; handle_gb28181->addCamera(fn); - int ret = openWithCustomIO((void *)&handle_gb28181, handle_gb28181->readData, options); + int ret = openWithCustomIO(handle_gb28181, handle_gb28181->readData, options); if(ret < 0){ logIt("do openWithCustomIO failed:%d",ret); } @@ -136,15 +138,25 @@ return false; } + logIt("there are %d stream", ctx_->nb_streams); + for (int i = 0; i < ctx_->nb_streams; ++i) { - switch(ctx_->streams[i]->codecpar->codec_type){ - case AVMEDIA_TYPE_VIDEO: - vs_idx_ = i; - break; + auto type = ctx_->streams[i]->codecpar->codec_type; + if (type == AVMEDIA_TYPE_VIDEO){ + vs_idx_ = i; - default: - break; + auto in = ctx_->streams[i]; + if(in->r_frame_rate.num >=1 && in->r_frame_rate.den >= 1){ + fps_ = av_q2d(in->r_frame_rate); + }else if(in->avg_frame_rate.num >=1 && in->avg_frame_rate.den >= 1){ + fps_ = av_q2d(in->avg_frame_rate); + } + logIt("video stream time base %d : %d", in->time_base.num, in->time_base.den); + } + if (type == AVMEDIA_TYPE_AUDIO){ + as_idx_ = i; + logIt("audio stream time base %d : %d", ctx_->streams[i]->time_base.num, ctx_->streams[i]->time_base.den); } } return true; @@ -250,43 +262,52 @@ return true; } - AVStream *FormatIn::getStream(int type){ - return ctx_->streams[vs_idx_]; + AVStream *FormatIn::getStream(int type/*=-1*/){ + if (type == -1){ + return ctx_->streams[vs_idx_]; + } + + if (type == ctx_->streams[vs_idx_]->codecpar->codec_type) + return ctx_->streams[vs_idx_]; + if (type == ctx_->streams[as_idx_]->codecpar->codec_type) + return ctx_->streams[as_idx_]; + + return NULL; } AVCodecContext *FormatIn::getCodecContext(int type){ return dec_ctx_; } - bool FormatIn::readPacket(AVPacket &pkt_out, int stream_index){ - - bool founded = false; - while (!founded){ - const int ret = av_read_frame(ctx_, &pkt_out); - if(ret < 0){ - // logIt("read frame from %s failed:%s", - // ctx_->filename,getAVErrorDesc(ret).c_str()); - - return false; - } - if(pkt_out.stream_index == stream_index){ - founded = true; - }else{ - av_free_packet(&pkt_out); - av_init_packet(&pkt_out); - pkt_out.data = NULL; - pkt_out.size = 0; - } + bool FormatIn::isVideoPkt(AVPacket &pkt){ + if (pkt.stream_index == vs_idx_){ + return true; } - pkt_out.stream_index = 0; + return false; + } + + bool FormatIn::isAudioPkt(AVPacket &pkt){ + if (pkt.stream_index == as_idx_){ + return true; + } + return false; + } + + bool FormatIn::readPacket(AVPacket &pkt_out){ + + const int ret = av_read_frame(ctx_, &pkt_out); + if(ret < 0){ + return false; + } + return true; } - bool FormatIn::readPacket(std::shared_ptr<CodedData> &data, int stream_index){ + bool FormatIn::readPacket(std::shared_ptr<CodedData> &data){ AVPacket &pkt(data->getAVPacket()); - return readPacket(pkt, getStream()->index); + return readPacket(pkt); } int FormatIn::decode(AVFrame* &frame, AVPacket &pkt){ diff --git a/csrc/ffmpeg/format/FormatIn.hpp b/csrc/ffmpeg/format/FormatIn.hpp index a569524..ca14f81 100644 --- a/csrc/ffmpeg/format/FormatIn.hpp +++ b/csrc/ffmpeg/format/FormatIn.hpp @@ -37,8 +37,8 @@ bool openCodec(const int type, AVDictionary **options); - bool readPacket(AVPacket &pkt_out, int stream_index = 0); - bool readPacket(std::shared_ptr<CodedData> &data, int stream_index = 0); + bool readPacket(AVPacket &pkt_out); + bool readPacket(std::shared_ptr<CodedData> &data); int decode(AVFrame* &frame, AVPacket &pkt); int decode(std::shared_ptr<FrameData> &frame_data, @@ -47,18 +47,22 @@ int readFrame(AVFrame* &frame); int readFrame(std::shared_ptr<FrameData> &frame_data); + bool isVideoPkt(AVPacket &pkt); + bool isAudioPkt(AVPacket &pkt); private: bool allocCodec(AVCodec *dec, AVStream *s, AVDictionary **options); public: - AVStream *getStream(int type = 0); + AVStream *getStream(int type = -1); AVCodecContext *getCodecContext(int type = 0); + const double getFPS()const{return fps_;} private: AVFormatContext *ctx_; AVCodecContext *dec_ctx_; int vs_idx_; + int as_idx_; bool hw_accl_; - + double fps_; private: AVIOContext *io_ctx_; uint8_t *read_io_buff_; diff --git a/csrc/ffmpeg/format/FormatOut.cpp b/csrc/ffmpeg/format/FormatOut.cpp index a6e8c3c..0c6958f 100644 --- a/csrc/ffmpeg/format/FormatOut.cpp +++ b/csrc/ffmpeg/format/FormatOut.cpp @@ -32,6 +32,7 @@ ,record_(false) ,fps_(0.0f) ,format_name_("mp4") + ,streams_(NULL) {} FormatOut::~FormatOut() @@ -265,42 +266,16 @@ } ////////////////////////////////////////////////////////////////////////// - FormatOut::FormatOut(AVStream *in, const char *format_name) + FormatOut::FormatOut(const double fps, const char *format_name) :FormatOut(){ format_name_ = format_name; - if(in->r_frame_rate.num >=1 && in->r_frame_rate.den >= 1){ - fps_ = av_q2d(in->r_frame_rate); - }else if(in->avg_frame_rate.num >=1 && in->avg_frame_rate.den >= 1){ - fps_ = av_q2d(in->avg_frame_rate); - } - } - - - bool FormatOut::copyCodecFromIn(AVStream *in){ - - v_s_ = avformat_new_stream(ctx_, in->codec->codec); - if(!v_s_){ - return false; - } - - int ret = avcodec_copy_context(v_s_->codec, in->codec); - if (ret < 0){ - logIt("can't copy codec from in error:%s", getAVErrorDesc(ret).c_str()); - - return false; - } - - if (ctx_->oformat->flags & AVFMT_GLOBALHEADER) - { - v_s_->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; - } - return true; + fps_ = fps; } bool FormatOut::openResource(const char *filename, const int flags){ - if((ctx_->flags & AVFMT_NOFILE) != AVFMT_NOFILE){ + if((ctx_->oformat->flags & AVFMT_NOFILE) != AVFMT_NOFILE){ const int err = avio_open2(&ctx_->pb, filename, flags, NULL, NULL); if(err < 0) @@ -320,7 +295,43 @@ } return true; } - bool FormatOut::JustWriter(AVStream *in, const char *filename){ + + bool FormatOut::copyCodecFromIn(std::vector<AVStream*> in){ + auto count = in.size(); + + for(int i = 0; i < count; i++) + { //鏍规嵁杈撳叆娴佸垱寤鸿緭鍑烘祦 + AVStream *in_stream = in[i]; + AVStream *out_stream = avformat_new_stream(ctx_, in_stream->codec->codec); + if(!out_stream) + { + logIt("Failed allocating output stream.\n"); + return false; + } + + if (in_stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){ + v_s_ = out_stream; + } + //灏嗚緭鍑烘祦鐨勭紪鐮佷俊鎭鍒跺埌杈撳叆娴� + auto ret = avcodec_copy_context(out_stream->codec, in_stream->codec); + if(ret<0) + { + logIt("Failed to copy context from input to output stream codec context\n"); + return false; + } + out_stream->codec->codec_tag = 0; + + if(ctx_->oformat->flags & AVFMT_GLOBALHEADER) + out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; + + } + + streams_ = in; + + return true; + } + + bool FormatOut::JustWriter(std::vector<AVStream*> in, const char *filename){ if(ctx_){ clear(); } @@ -386,7 +397,7 @@ return true; } - void FormatOut::adjustPTS(AVPacket &pkt, const int64_t &frame_cnt){ + void FormatOut::adjustVideoPTS(AVPacket &pkt, const int64_t &frame_cnt){ int64_t time_stamp = frame_cnt; pkt.pos = -1; @@ -404,7 +415,70 @@ pkt.dts = pkt.pts; pkt.duration = av_rescale_q(calc_duration, time_base_q, time_base); //(double)(calc_duration)*(double)(av_q2d(time_base_q)) / (double)(av_q2d(time_base)); - // logIt("FRAME ID: %lld, PTS : %lld, DTS : %lld", frame_cnt, pkt.pts, pkt.dts); + // logIt("FRAME ID: %lld, PTS : %lld, DTS : %lld", frame_cnt, pkt.pts, pkt.dts); + } + + void FormatOut::adjustPTS(AVPacket &pkt, const int64_t &frame_cnt){ + if (streams_.size() == 1){ + return adjustVideoPTS(pkt, frame_cnt); + } + + if (pkt.stream_index >= streams_.size()){ + logIt("adjustPTS pkt stream index too much"); + return; + } + + AVStream *in_stream,*out_stream; + + in_stream = streams_[pkt.stream_index]; + out_stream = ctx_->streams[pkt.stream_index]; + + // logIt("stream %d time_base %d : %d", pkt.stream_index, in_stream->time_base.num, in_stream->time_base.den); + // logIt("out time_base %d : %d", out_stream->time_base.num, out_stream->time_base.den); + + std::string type("video"); + if (in_stream->codecpar->codec_type == 1){ + type = "audio"; + } + + // logIt("BEFORE stream %d type: %s, pts: %lld, dts: %lld, duration: %lld", + // pkt.stream_index, type.c_str(), pkt.pts, pkt.pts, pkt.duration); + //copy packet + //杞崲 PTS/DTS 鏃跺簭 + pkt.pts = av_rescale_q_rnd(pkt.pts,in_stream->time_base,out_stream->time_base,(enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); + pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX)); + //printf("pts %d dts %d base %d\n",pkt.pts,pkt.dts, in_stream->time_base); + pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base); + pkt.pos = -1; + + // logIt("AFTER stream %d type: %s, pts: %lld, dts: %lld, duration: %lld", + // pkt.stream_index, type.c_str(), pkt.pts, pkt.pts, pkt.duration); + + // //姝hile寰幆涓苟闈炴墍鏈塸acket閮芥槸瑙嗛甯э紝褰撴敹鍒拌棰戝抚鏃惰褰曚竴涓嬶紝浠呮鑰屽凡 + // if(pkt.stream_index==video_index) + // { + // printf("Receive %8d video frames from input URL\n",frame_index); + // frame_index++; + // } + + // //灏嗗寘鏁版嵁鍐欏叆鍒版枃浠躲�� + // ret = av_interleaved_write_frame(ofmt_ctx,&pkt); + // if(ret < 0) + // { + // /** + // 褰撶綉缁滄湁闂鏃讹紝瀹规槗鍑虹幇鍒拌揪鍖呯殑鍏堝悗涓嶄竴鑷达紝pts鏃跺簭娣蜂贡浼氬鑷� + // av_interleaved_write_frame鍑芥暟鎶� -22 閿欒銆傛殏鏃跺厛涓㈠純杩欎簺杩熸潵鐨勫抚鍚� + // 鑻ユ墍澶ч儴鍒嗗寘閮芥病鏈塸ts鏃跺簭锛岄偅灏辫鐪嬫儏鍐佃嚜宸辫ˉ涓婃椂搴忥紙姣斿杈冨墠涓�甯ф椂搴�+1锛夊啀鍐欏叆銆� + // */ + // if(ret==-22){ + // continue; + // }else{ + // printf("Error muxing packet.error code %d\n" , ret); + // break; + // } + + // } + } bool FormatOut::writeFrame(AVPacket &pkt, const int64_t &frame_cnt, @@ -429,11 +503,11 @@ ret = av_write_frame(ctx_, &pkt); } - if(ret < 0){ - return false; + if(ret < -22 || ret == 0){ + return true; } - return true; + return false; } bool FormatOut::writeTrailer(){ diff --git a/csrc/ffmpeg/format/FormatOut.hpp b/csrc/ffmpeg/format/FormatOut.hpp index 35575d7..2fbe47b 100644 --- a/csrc/ffmpeg/format/FormatOut.hpp +++ b/csrc/ffmpeg/format/FormatOut.hpp @@ -4,6 +4,7 @@ #include <stdlib.h> #include <memory> #include <string> +#include <vector> struct AVFormatContext; struct AVStream; @@ -26,7 +27,7 @@ FormatOut(VideoProp &prop, const char *filename, char *format_name = NULL); - FormatOut(AVStream *in, const char *format_name); + FormatOut(const double fps, const char *format_name); void clear(); public: @@ -39,14 +40,15 @@ int encode(std::shared_ptr<CodedData> &data,AVFrame *frame); public: - bool copyCodecFromIn(AVStream *in); + bool copyCodecFromIn(std::vector<AVStream*> in); bool openResource(const char *filename, const int flags); bool closeResource(); - bool JustWriter(AVStream *in, const char *filename); + bool JustWriter(std::vector<AVStream*> in, const char *filename); bool EncodeWriter(const char *filename); bool writeFrame(AVPacket &pkt, const int64_t &frame_cnt, bool interleaved = true); void adjustPTS(AVPacket &pkt, const int64_t &frame_cnt); + void adjustVideoPTS(AVPacket &pkt, const int64_t &frame_cnt); bool endWriter(); bool writeHeader(AVDictionary **options = NULL); @@ -75,6 +77,8 @@ double fps_; std::string format_name_; + // rec + std::vector<AVStream*> streams_; }; } #endif \ No newline at end of file diff --git a/csrc/worker/decoder.cpp b/csrc/worker/decoder.cpp index 0a9fb46..4cd1f8d 100644 --- a/csrc/worker/decoder.cpp +++ b/csrc/worker/decoder.cpp @@ -66,6 +66,7 @@ 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(); diff --git a/csrc/worker/rec.cpp b/csrc/worker/rec.cpp index 4307d6e..797e047 100644 --- a/csrc/worker/rec.cpp +++ b/csrc/worker/rec.cpp @@ -40,7 +40,7 @@ list_recInfo_.emplace_back(info); } - std::unique_ptr<buz::Recorder> rec::startRec(std::string id, std::string dir, const int mind, const int maxd){ + std::unique_ptr<buz::Recorder> rec::startRec(std::string id, std::string dir, const int mind, const int maxd, const bool audio){ if(!recRef_){ logIt("Init wrapper first"); return nullptr; @@ -54,7 +54,7 @@ int trycnt = 0; while(trycnt < 100){ - auto ret = rec->Run(dir.c_str(), mind, maxd); + auto ret = rec->Run(dir.c_str(), mind, maxd, audio); if(ret == 0) break; usleep(200000); } @@ -133,7 +133,7 @@ return recRef_ != NULL; } - void rec::NewRec(const char* id, const char *output, const int mindur, const int maxdur){ + void rec::NewRec(const char* id, const char *output, const int mindur, const int maxdur, const bool audio){ std::string rid(id); std::string dir(output); @@ -145,7 +145,7 @@ if (map_rec_.find(rid) != map_rec_.end()){ map_rec_.erase(rid); } - map_rec_[rid] = startRec(rid, dir, mindur, maxdur); + map_rec_[rid] = startRec(rid, dir, mindur, maxdur, audio); } } diff --git a/csrc/worker/rec.hpp b/csrc/worker/rec.hpp index c489676..5ac00a9 100644 --- a/csrc/worker/rec.hpp +++ b/csrc/worker/rec.hpp @@ -53,11 +53,11 @@ // 涓㈠純缂撳瓨 int shrinkCache(); // 鍒涘缓褰曞儚瀹炰緥寮�濮嬪綍鍍� - std::unique_ptr<buz::Recorder> startRec(std::string id, std::string dir, const int mind, const int maxd); + std::unique_ptr<buz::Recorder> startRec(std::string id, std::string dir, const int mind, const int maxd, const bool audio); // 娓呴櫎缂撳瓨,鏂嚎閲嶈繛鏃堕渶瑕� void clear(); public: - void NewRec(const char* id, const char *output, const int mindur, const int maxdur); + void NewRec(const char* id, const char *output, const int mindur, const int maxdur, const bool audio); // 鍑嗗濂藉綍鍍� void Load(ffwrapper::FormatIn *in); diff --git a/csrc/worker/stream.cpp b/csrc/worker/stream.cpp index 0f8dadc..1828304 100644 --- a/csrc/worker/stream.cpp +++ b/csrc/worker/stream.cpp @@ -1,10 +1,13 @@ #include "stream.hpp" #include "../ffmpeg/data/CodedData.hpp" +#include "../ffmpeg/format/FormatIn.hpp" namespace cffmpeg_wrap{ - stream::stream(const int maxSize) - :max_size_(maxSize) + stream::stream(ffwrapper::FormatIn *in, const int maxSize) + :streamRef_(in) + ,max_size_(maxSize) + ,audio_(false) {} stream::~stream(){ @@ -14,6 +17,13 @@ int stream::SetPacket(std::shared_ptr<ffwrapper::CodedData> data){ if (data){ + + auto audio = streamRef_->isAudioPkt(data->getAVPacket()); + // 濡傛灉鍖呮槸闊抽鍖�,浣嗘槸涓嶄娇鐢ㄩ煶棰�,鐩存帴杩斿洖 + if (!audio_ && audio){ + return 0; + } + std::lock_guard<std::mutex> locker(mutex_avpkt_); list_avpkt_.push_back(data); diff --git a/csrc/worker/stream.hpp b/csrc/worker/stream.hpp index 6c87ff6..b738ada 100644 --- a/csrc/worker/stream.hpp +++ b/csrc/worker/stream.hpp @@ -6,6 +6,7 @@ #include <memory> namespace ffwrapper{ + class FormatIn; class CodedData; } @@ -15,13 +16,16 @@ private: std::list<std::shared_ptr<ffwrapper::CodedData> > list_avpkt_; std::mutex mutex_avpkt_; + ffwrapper::FormatIn *streamRef_; const int max_size_; + bool audio_; public: - explicit stream(const int maxSize); + stream(ffwrapper::FormatIn *in, const int maxSize); ~stream(); int SetPacket(std::shared_ptr<ffwrapper::CodedData> data); void GetPacket(unsigned char **pktData, int *size, int *key); + void AudioSwitch(const bool a){audio_ = a;} }; } diff --git a/csrc/wrapper.cpp b/csrc/wrapper.cpp index 63bb661..9f0e4e7 100644 --- a/csrc/wrapper.cpp +++ b/csrc/wrapper.cpp @@ -44,6 +44,7 @@ ,scale_w_(0) ,scale_h_(0) ,scale_f_(SWS_POINT) + ,audio_(false) ,gb_(0) ,cpu_(0) ,thread_(nullptr) @@ -72,20 +73,6 @@ } } - void Wrapper::ScalePicture(const int w, const int h, const int flags){ - scale_w_ = w; - scale_f_ = flags; - scale_h_ = h; - } - - void Wrapper::GB28181(){ - gb_ = 1; - } - - void Wrapper::CPUDec(){ - cpu_ = 1; - } - std::unique_ptr<ffwrapper::FormatIn> Wrapper::init_reader(const char* input){ VideoProp prop; @@ -106,7 +93,7 @@ } if(flag == 0){ if(!in->findStreamInfo(NULL)){ - logIt("yolo can't find video stream\n"); + logIt("can't find video stream\n"); return nullptr; } @@ -131,15 +118,26 @@ return 0; } + void Wrapper::AudioSwitch(const bool a){ + audio_ = a; + if (stream_){ + stream_->AudioSwitch(a); + } + } + void Wrapper::init_worker(ffwrapper::FormatIn *in){ if (rec_->Loaded() && stream_ && decoder_) return; - stream_ = new stream(3 * 25); + stream_ = new stream(in, 3 * 25); + stream_->AudioSwitch(audio_); + decoder_ = new decoder(in, scale_w_, scale_h_, scale_f_); + rec_->Load(in); if(fn_rec_lazy_) fn_rec_lazy_(in); } - void Wrapper::run_worker(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id){ + void Wrapper::run_worker(ffwrapper::FormatIn *in, std::shared_ptr<ffwrapper::CodedData> data, int64_t &id){ + if (stream_) stream_->SetPacket(data); if (decoder_) decoder_->SetFrame(data, id); if (rec_->Loaded()) rec_->SetPacket(data, id); @@ -172,7 +170,7 @@ break; } - run_worker(data, id); + run_worker(in.get(), data, id); id++; } @@ -180,14 +178,14 @@ } } - void Wrapper::BuildRecorder(const char* id, const char *output, const int mindur, const int maxdur){ + void Wrapper::BuildRecorder(const char* id, const char *output, const int mindur, const int maxdur, const bool audio){ if (rec_->Loaded()){ - rec_->NewRec(id, output, mindur, maxdur); + rec_->NewRec(id, output, mindur, maxdur, audio); }else{ std::string rid(id), dir(output); fn_rec_lazy_ = - [=](ffwrapper::FormatIn *in){rec_->NewRec(rid.c_str(), dir.c_str(), mindur, maxdur);}; + [=](ffwrapper::FormatIn *in){rec_->NewRec(rid.c_str(), dir.c_str(), mindur, maxdur, audio);}; } } diff --git a/csrc/wrapper.hpp b/csrc/wrapper.hpp index 044b4ba..3b4aa7b 100644 --- a/csrc/wrapper.hpp +++ b/csrc/wrapper.hpp @@ -37,19 +37,24 @@ std::unique_ptr<ffwrapper::FormatIn> init_reader(const char* input); void init_worker(ffwrapper::FormatIn *in); - void run_worker(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id); + void run_worker(ffwrapper::FormatIn *in, std::shared_ptr<ffwrapper::CodedData> data, int64_t &id); void deinit_worker(); public: int RunStream(const char* input); private: void run_stream_thread(); public: //recorder - void BuildRecorder(const char* id,const char *dir, const int mind, const int maxd); + void BuildRecorder(const char* id,const char *dir, const int mind, const int maxd, const bool audio); int FireRecorder(const char* sid,const int64_t &id); void GetInfoRecorder(std::string &recID, int &index, std::string &path); - void ScalePicture(const int w, const int h, const int flags); - void GB28181(); - void CPUDec(); + void ScalePicture(const int w, const int h, const int flags){ + scale_w_ = w; + scale_h_ = h; + scale_f_ = flags; + } + void GB28181(){gb_ = 1;} + void CPUDec(){cpu_ = 1;} + void AudioSwitch(const bool a); public: //decoder void BuildDecoder(); void GetPicDecoder(unsigned char **data, int *w, int *h, int64_t *id); @@ -59,7 +64,7 @@ // stream 鍙傛暟 std::string input_url_; int scale_w_, scale_h_, scale_f_; - + bool audio_; int gb_, cpu_; // decoder 鍙傛暟 std::unique_ptr<std::thread> thread_; diff --git a/goffmpeg.go b/goffmpeg.go index 1efcb8d..bf2df6c 100644 --- a/goffmpeg.go +++ b/goffmpeg.go @@ -134,13 +134,13 @@ } // BuildRecorder build recorder -func (h *GoFFMPEG) BuildRecorder(sid, output string, mind, maxd int) { +func (h *GoFFMPEG) BuildRecorder(sid, output string, mind, maxd, audio int) { out := C.CString(output) defer C.free(unsafe.Pointer(out)) csid := C.CString(sid) defer C.free(unsafe.Pointer(csid)) - C.wrap_fn_recorder(h.ffmpeg, csid, out, C.int(mind), C.int(maxd)) + C.wrap_fn_recorder(h.ffmpeg, csid, out, C.int(mind), C.int(maxd), C.int(audio)) } // GetInfoRecorder info diff --git a/libcffmpeg.c b/libcffmpeg.c index fda4217..e1858ba 100644 --- a/libcffmpeg.c +++ b/libcffmpeg.c @@ -87,8 +87,8 @@ fn_cpu(h); } -void wrap_fn_recorder(const cffmpeg h, const char* id, const char* dir, int mind, int maxd){ - fn_recorder(h, id, dir, mind, maxd); +void wrap_fn_recorder(const cffmpeg h, const char* id, const char* dir, int mind, int maxd, int audio){ + fn_recorder(h, id, dir, mind, maxd, audio); } void wrap_fn_fire_recorder(const cffmpeg h, const char* sid, const int64_t id){ diff --git a/libcffmpeg.h b/libcffmpeg.h index cf8d212..ce4d747 100644 --- a/libcffmpeg.h +++ b/libcffmpeg.h @@ -16,7 +16,7 @@ typedef void (*lib_cffmpeg_scale)(const cffmpeg, const int, const int, const int); typedef void (*lib_cffmpeg_gb28181)(const cffmpeg); typedef void (*lib_cffmpeg_cpu)(const cffmpeg); -typedef void (*lib_cffmpeg_recorder)(const cffmpeg, const char*, const char*, int, int); +typedef void (*lib_cffmpeg_recorder)(const cffmpeg, const char*, const char*, int, int, int); typedef void (*lib_cffmpeg_fire_recorder)(const cffmpeg, const char*, const int64_t); typedef void (*lib_cffmpeg_info_recorder)(const cffmpeg, int*, char**, int*, char**, int*); typedef void (*lib_cffmpeg_decoder)(const cffmpeg); @@ -48,7 +48,7 @@ void wrap_fn_scale(const cffmpeg h, const int wid, const int hei, const int flags); void wrap_fn_run_gb28181(const cffmpeg h); void wrap_fn_use_cpu(const cffmpeg h); -void wrap_fn_recorder(const cffmpeg h, const char* id, const char* dir, int mind, int maxd); +void wrap_fn_recorder(const cffmpeg h, const char* id, const char* dir, int mind, int maxd, int audio); void wrap_fn_fire_recorder(const cffmpeg h, const char *sid, const int64_t id); void wrap_fn_info_recorder(const cffmpeg, int* index, char** recid, int* recidLen, char** fpath, int* pathLen); void wrap_fn_decoder(const cffmpeg h); -- Gitblit v1.8.0