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