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 --- csrc/ffmpeg/format/FormatOut.cpp | 144 ++++++++++++++++++++++++++++++++++++----------- 1 files changed, 109 insertions(+), 35 deletions(-) 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(){ -- Gitblit v1.8.0