diff --git a/src/decoder/dvpp/DvppDecoder.cpp b/src/decoder/dvpp/DvppDecoder.cpp index 2f5d946..5c9a6b6 100755 --- a/src/decoder/dvpp/DvppDecoder.cpp +++ b/src/decoder/dvpp/DvppDecoder.cpp @@ -245,8 +245,6 @@ void DvppDecoder::close(){ if(m_read_thread != 0){ pthread_join(m_read_thread,0); } - - m_recoderManager.close(); } void DvppDecoder::setPostDecArg(const void* postDecArg){ @@ -442,6 +440,8 @@ void DvppDecoder::read_thread() { decode_finished_cbk(m_finishedDecArg); } + m_recoderManager.close(); + LOG_INFO("[{}]- read thread exit.", m_dec_name); m_bFinished = true; release_ffmpeg(); diff --git a/src/decoder/dvpp/FFRecoder.cpp b/src/decoder/dvpp/FFRecoder.cpp index dd47502..4c99648 100644 --- a/src/decoder/dvpp/FFRecoder.cpp +++ b/src/decoder/dvpp/FFRecoder.cpp @@ -24,7 +24,6 @@ FFRecoder::FFRecoder() FFRecoder::~FFRecoder() { - uninit(); } @@ -125,7 +124,7 @@ bool FFRecoder::init(AVStream* stream, AVCodecContext* avctx, const char* outfil codec_ctx_ = (AVCodecContext*)av_malloc(sizeof(AVCodecContext)); avcodec_copy_context(codec_ctx_, avctx); - codec_ctx_->time_base = stream->time_base; + codec_ctx_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; m_inStream = stream; // [2] 创建输出上下文 @@ -133,11 +132,19 @@ bool FFRecoder::init(AVStream* stream, AVCodecContext* avctx, const char* outfil // [3] 添加输出视频流 out_stream_ = avformat_new_stream(fmt_ctx_, nullptr); + out_stream_->id = 0; out_stream_->codecpar->codec_tag = 0; avcodec_parameters_from_context(out_stream_->codecpar, codec_ctx_); - // out_stream_->time_base = { 1,30 }; + // out_stream_->time_base = { 1,25 }; out_stream_->time_base = stream->time_base; + out_stream_->r_frame_rate = stream->r_frame_rate; + out_stream_->avg_frame_rate = stream->r_frame_rate; + + codec_ctx_->time_base = out_stream_->time_base; + + av_opt_set(out_stream_->codec->priv_data, "preset", "ultrafast", 0); + av_opt_set(out_stream_->codec->priv_data, "tune", "zerolatency", 0); av_dump_format(fmt_ctx_, out_stream_->id, outfile_name, 1); @@ -154,6 +161,18 @@ bool FFRecoder::init(AVStream* stream, AVCodecContext* avctx, const char* outfil return true; } +void FFRecoder::release() { + av_write_trailer(fmt_ctx_); + + avcodec_close(fmt_ctx_->streams[0]->codec); + av_freep(&fmt_ctx_->streams[0]->codec); + av_freep(&fmt_ctx_->streams[0]); + + avio_close(fmt_ctx_->pb); + av_free(fmt_ctx_); + fmt_ctx_ = nullptr; +} + void FFRecoder::uninit() { //if (out_buffer) { @@ -250,8 +269,7 @@ bool FFRecoder::write_pkt(AVPacket *pkt) { // update_pts(pkt); // pkt->stream_index = out_stream_->index; - // if(pkt->pts==AV_NOPTS_VALUE) - { + if(pkt->pts==AV_NOPTS_VALUE) { // printf("frame_index:%d\n", frame_index); //Write PTS AVRational time_base1 = codec_ctx_->time_base; @@ -262,15 +280,15 @@ bool FFRecoder::write_pkt(AVPacket *pkt) { pkt->dts = pkt->pts; pkt->duration = (double)calc_duration / (double)(av_q2d(time_base1)*AV_TIME_BASE); frame_index++; - } + } // Convert PTS/DTS pkt->pts = av_rescale_q_rnd(pkt->pts, codec_ctx_->time_base, out_stream_->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); pkt->dts = av_rescale_q_rnd(pkt->dts, codec_ctx_->time_base, out_stream_->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)); pkt->duration = av_rescale_q(pkt->duration, codec_ctx_->time_base, out_stream_->time_base); + pkt->pos = -1; - pkt->stream_index = out_stream_->index; - + fmt_ctx_->duration += pkt->duration; // 将数据写入到输出流 int ret = av_interleaved_write_frame(fmt_ctx_, pkt); @@ -336,6 +354,11 @@ bool FFRecoder::flush() return write_frame(nullptr); } +bool FFRecoder::flush_pkt() +{ + return av_interleaved_write_frame(fmt_ctx_, nullptr); +} + bool FFRecoder::bgr_to_yuv420p(const uint8_t* const buf_bgr, uint8_t* const buf_420p) { // 分配转换上下文 diff --git a/src/decoder/dvpp/FFRecoder.h b/src/decoder/dvpp/FFRecoder.h index 0cfaa7c..ec99c15 100644 --- a/src/decoder/dvpp/FFRecoder.h +++ b/src/decoder/dvpp/FFRecoder.h @@ -26,6 +26,8 @@ public: // AVPacket 方式 bool init(AVStream* stream, AVCodecContext* avctx, const char* outfile_name); bool write_pkt(AVPacket *pkt); + bool flush_pkt(); + void release(); private: bool bgr_to_yuv420p(const uint8_t* const buf_bgr, uint8_t* const buf_420p); diff --git a/src/decoder/dvpp/FFRecoderTaskManager.cpp b/src/decoder/dvpp/FFRecoderTaskManager.cpp index 2ba2a0f..38d0691 100644 --- a/src/decoder/dvpp/FFRecoderTaskManager.cpp +++ b/src/decoder/dvpp/FFRecoderTaskManager.cpp @@ -393,7 +393,7 @@ void FFRecoderTaskManager::recode_thread2() { end_frame_nb = (*it_save)->frame_nb; } - // ffrecoder.flush(); + ffrecoder.flush_pkt(); ffrecoder.uninit(); // 发送mq消息 diff --git a/src/decoder/test_recoder.cpp b/src/decoder/test_recoder.cpp index 7b44c83..3afa4cf 100644 --- a/src/decoder/test_recoder.cpp +++ b/src/decoder/test_recoder.cpp @@ -64,7 +64,7 @@ int main(){ MgrDecConfig config; config.name = task_id; - config.cfg.uri = "rtsp://122.97.218.170:8604/openUrl/LBBYTra?params=eyJwcm90b2NhbCI6InJ0c3AiLCJjbGllbnRUeXBlIjoib3Blbl9hcGkiLCJleHByaWVUaW1lIjotMSwicHJvdG9jb2wiOiJydHNwIiwiZXhwaXJlVGltZSI6MzAwLCJlbmFibGVNR0MiOnRydWUsImV4cGFuZCI6InN0YW5kYXJkPXJ0c3Amc3RyZWFtZm9ybT1ydHAiLCJhIjoiOTgzYjRjMmUxMThlNGU1OTlkYThmMTI3NTkyMGViODV8MXwwfDEiLCJ0IjoxfQ=="; + config.cfg.uri = "rtsp://admin:ad123456@192.168.60.165:554/cam/realmonitor?channel=1&subtype=0"; config.cfg.post_decoded_cbk = post_decod_cbk; config.cfg.decode_finished_cbk = decode_finished_cbk; config.cfg.force_tcp = true; // rtsp用tcp