From efd35d36560a31fd63fc091433026cec9eccefd4 Mon Sep 17 00:00:00 2001 From: Hu Chunming <2657262686@qq.com> Date: Wed, 10 Jul 2024 11:23:45 +0800 Subject: [PATCH] pkt释放移到recoder里面,尝试修复encoder的时候data为null的问题 --- src/decoder/dvpp/DvppDecoder.cpp | 36 +++++++++++++++++------------------- src/decoder/dvpp/DvppStreamDecoder.cpp | 18 +++++++++++------- src/decoder/dvpp/FFRecoderTaskManager.cpp | 23 ++++++++++++++++++++--- 3 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/decoder/dvpp/DvppDecoder.cpp b/src/decoder/dvpp/DvppDecoder.cpp index 53060ed..251ff30 100644 --- a/src/decoder/dvpp/DvppDecoder.cpp +++ b/src/decoder/dvpp/DvppDecoder.cpp @@ -544,8 +544,6 @@ void DvppDecoder::read_thread() { CHECK_AND_BREAK(aclvdecSetChannelDescOutPicFormat(vdecChannelDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420), "aclvdecSetChannelDescOutPicFormat failed"); CHECK_AND_BREAK(aclvdecCreateChannel(vdecChannelDesc), "aclvdecCreateChannel failed"); - AVPacket* pkt = av_packet_alloc(); - av_init_packet( pkt ); unsigned long long frame_nb = 0; while (m_bRunning){ @@ -573,9 +571,12 @@ void DvppDecoder::read_thread() { m_last_read_ts = get_cur_time_ms(); } + AVPacket* pkt = av_packet_alloc(); + av_init_packet( pkt ); int result = av_read_frame(fmt_ctx, pkt); if (result == AVERROR_EOF || result < 0){ - av_packet_unref(pkt); + av_packet_free(&pkt); + pkt = nullptr; LOG_WARN("[{}]- Failed to read frame!", m_dec_name); break; } @@ -588,7 +589,8 @@ void DvppDecoder::read_thread() { } if (m_dec_keyframe && !(pkt->flags & AV_PKT_FLAG_KEY)) { - av_packet_unref(pkt); + av_packet_free(&pkt); + pkt = nullptr; continue; } @@ -597,23 +599,18 @@ void DvppDecoder::read_thread() { ret = av_bsf_send_packet(h264bsfc, pkt); if(ret < 0) { LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name); - av_packet_unref(pkt); + av_packet_free(&pkt); + pkt = nullptr; continue; } + frame_nb++; int nSended = -1; while ((ret = av_bsf_receive_packet(h264bsfc, pkt)) == 0) { - if(!m_bRunning){ break; } - - frame_nb++; - #ifdef USE_VILLAGE - m_recoderManager.cache_pkt(pkt, frame_nb, m_dec_name); - #endif nSended = sendPkt(vdecChannelDesc, pkt, frame_nb); - } if(nSended < 0) { @@ -621,14 +618,15 @@ void DvppDecoder::read_thread() { m_bRunning=false; break; } - } - - // 音频等其他分量的情形 - av_packet_unref(pkt); - } - av_packet_free(&pkt); - pkt = nullptr; + #ifdef USE_VILLAGE + m_recoderManager.cache_pkt(pkt, frame_nb, m_dec_name); + #endif + } else { + av_packet_free(&pkt); + pkt = nullptr; + } + } if (vdecChannelDesc) { sendVdecEos(vdecChannelDesc); diff --git a/src/decoder/dvpp/DvppStreamDecoder.cpp b/src/decoder/dvpp/DvppStreamDecoder.cpp index 9a42e54..cf82ede 100644 --- a/src/decoder/dvpp/DvppStreamDecoder.cpp +++ b/src/decoder/dvpp/DvppStreamDecoder.cpp @@ -474,7 +474,7 @@ int DvppStreamDecoder::SendData(int videoType, char* data, int len, int isKey, u if(ret < 0) { LOG_ERROR("[{}]- av_bsf_send_packet error!", m_dec_name); ret = -3; - break;; + break; } int nSended = -1; @@ -484,21 +484,25 @@ int DvppStreamDecoder::SendData(int videoType, char* data, int len, int isKey, u } m_frame_nb++; - - #ifdef USE_VILLAGE - m_recoderManager.cache_pkt(pkt, m_frame_nb, m_dec_name); -#endif - // dvpp 解码 nSended = sendPkt(vdecChannelDesc, pkt, m_frame_nb, vdec_out_size); } +#ifdef USE_VILLAGE + m_recoderManager.cache_pkt(pkt, m_frame_nb, m_dec_name); +#endif + if(nSended < 0) { // 执行出错,强行结束整个任务 ret = -2; + break; } - +#ifdef USE_VILLAGE + //直接返回,不释放pkt,pkt在recoderManager释放 + return 0; +#elif ret = 0; +#endif } } while (0); diff --git a/src/decoder/dvpp/FFRecoderTaskManager.cpp b/src/decoder/dvpp/FFRecoderTaskManager.cpp index 83a9d2d..e2ce460 100644 --- a/src/decoder/dvpp/FFRecoderTaskManager.cpp +++ b/src/decoder/dvpp/FFRecoderTaskManager.cpp @@ -85,6 +85,23 @@ static AVPacket* packet_clone(AVPacket* pkt) { return new_pkt; } +static AVPacket* copy_packet(const AVPacket* src) +{ + AVPacket* dst = av_packet_alloc(); // 分配内存 + if (!dst) { + return NULL; + } + + // 复制所有字段 + av_packet_ref(dst, src); + + // 复制音视频数据 + dst->data = (uint8_t*)av_malloc(src->size); + memcpy(dst->data, src->data, src->size); + dst->size = src->size; + return dst; +} + void FFRecoderTaskManager::cache_pkt(AVPacket* pkt, long long frame_nb, string dec_name){ if(m_bExit) { // 任务退出了就不再缓存数据了 @@ -92,10 +109,10 @@ void FFRecoderTaskManager::cache_pkt(AVPacket* pkt, long long frame_nb, string d } // 考虑到一个AVPacket中的数据并不很大,为减少与解码模块的耦合度,方便管理,这里做一个clone - AVPacket *new_pkt = packet_clone(pkt); + // AVPacket *new_pkt = copy_packet(pkt); DataPacket* newDataPkt = new DataPacket(); - newDataPkt->pkt = new_pkt; + newDataPkt->pkt = pkt; newDataPkt->frame_nb = frame_nb; if(is_key_frame(pkt)){ @@ -296,7 +313,7 @@ void FFRecoderTaskManager::recode_thread() { LOG_ERROR("{} pkt is nullptr", recoderinfo.task_id); continue; } else if (pkt->data == nullptr || pkt->size <= 0){ - LOG_ERROR("{} pkt data is nullptr", recoderinfo.task_id); + LOG_ERROR("{} pkt data is nullptr or size is {}", recoderinfo.task_id, pkt->size); continue; } -- libgit2 0.21.4