@@ -1043,6 +1043,7 @@ class FFMpeg {
10431043#ifdef _DEBUG
10441044 auto err = GetErrorStr (response);
10451045#endif // _DEBUG
1046+ av_packet_unref (frames.pPacket );
10461047
10471048 break ;
10481049 }
@@ -1069,6 +1070,8 @@ class FFMpeg {
10691070 this ->bSeeking = false ;
10701071 convert_frame (frames.pLastFrame , callBack);
10711072
1073+ av_packet_unref (frames.pPacket );
1074+
10721075 return response;
10731076 }
10741077
@@ -1100,13 +1103,15 @@ class FFMpeg {
11001103 bReadFinish = (response == AVERROR_EOF);
11011104
11021105 const bool bStop = videoQueue.readFinish () && audioQueue.readFinish ();
1103-
11041106 if (bReadFinish && !bStop) {
11051107 videoQueue.stopBlock ();
11061108 audioQueue.stopBlock ();
11071109 }
11081110
1109- if (response < 0 ) { return response; }
1111+ if (response < 0 ) {
1112+ av_packet_unref (pPacket);
1113+ return response;
1114+ }
11101115
11111116 do {
11121117 if (pPacket->stream_index == video_stream_index) {
@@ -1126,9 +1131,6 @@ class FFMpeg {
11261131 }
11271132
11281133 inline void convert_frame (AVFrame* pFrame, const frameDataCallBack& callBack) {
1129- // data invalid, do not trigger callback, in case of get a black frame
1130- if (!pFrame->data [0 ]) { return ; }
1131-
11321134#ifdef HW_DECODE
11331135 if (bHWDecode) {
11341136 av_frame_unref (pSWFrame);
@@ -1140,11 +1142,15 @@ class FFMpeg {
11401142 throw FFMpegException (FFMpegException_HWDecodeFailed);
11411143 }
11421144
1143- pFrame = pSWFrame;
1145+ av_frame_unref (pFrame);
1146+ av_frame_move_ref (pFrame, pSWFrame);
11441147 }
11451148 }
11461149#endif // HW_DECODE
11471150
1151+ // data invalid, do not trigger callback, in case of get a black frame
1152+ if (!pFrame->data [0 ]) { return ; }
1153+
11481154 // Convert data to Bitmap data
11491155 // https://zhuanlan.zhihu.com/p/53305541
11501156
@@ -1172,29 +1178,29 @@ class FFMpeg {
11721178
11731179 sws_scale (swsContext, pFrame->data , pFrame->linesize , 0 , pFrame->height , bgr_buffer, linesize);
11741180
1175- // bgr_buffer[0] is the BGR raw data
1181+ // bgr_buffer[0] is the BGR raw data, aka p_global_bgr_buffer
11761182 callBack (bgr_buffer[0 ], linesize[0 ], pFrame->height );
1183+
1184+ av_frame_unref (pFrame);
11771185 }
11781186
11791187 inline int decode_frame (const frameDataCallBack& callBack) {
11801188 SyncState syncState;
11811189
11821190 do {
11831191 // calc delay
1184- syncState = get_syncState ();
1185-
1186- // syncState = SyncState::SYNC_SYNC;
1192+ syncState = get_syncState ();
11871193
11881194 // decode
11891195 switch (syncState) {
11901196 // video is faster, wait
1191- case FFMpeg:: SyncState::SYNC_VIDEOFASTER:
1197+ case SyncState::SYNC_VIDEOFASTER:
11921198 return 0 ;
11931199 // decode new video frame
1194- case FFMpeg:: SyncState::SYNC_CLOCKFASTER:
1195- case FFMpeg:: SyncState::SYNC_SYNC:
1200+ case SyncState::SYNC_CLOCKFASTER:
1201+ case SyncState::SYNC_SYNC:
11961202 int response = fill_decode ([&]() {
1197- return decode_videoFrame (pVLastFrame);
1203+ return decode_videoFrame (pVLastFrame);
11981204 });
11991205
12001206 if (response < 0 ) {
@@ -1226,6 +1232,7 @@ class FFMpeg {
12261232
12271233 // pFrame: frame to receive data
12281234 // pLastFrame: frame to ref latest updated pFrame
1235+ // This function will handle the av_packet_unref
12291236 inline int decode_frameCore (bool & bFinishState, bool & bSendEAgain,
12301237 const bool & bBlockState, PacketQueue& queue,
12311238 AVCodecContext* pCodecContext, AVPacket* pPacket, AVFrame* pFrame, AVFrame* pLastFrame,
@@ -1249,6 +1256,7 @@ class FFMpeg {
12491256 bSendEAgain = (response == AVERROR (EAGAIN));
12501257
12511258 if (response < 0 && !bSendEAgain && response != AVERROR_EOF) {
1259+ av_packet_unref (pPacket);
12521260 return response;
12531261 }
12541262
@@ -1258,9 +1266,7 @@ class FFMpeg {
12581266
12591267 // won't release if current packed didn't use
12601268 if (!bSendEAgain) {
1261- if (pPacket && pPacket->data ) {
1262- av_packet_unref (pPacket);
1263- }
1269+ av_packet_unref (pPacket);
12641270 }
12651271
12661272 if (bFinishState) {
@@ -1284,27 +1290,24 @@ class FFMpeg {
12841290 &FFMpeg::decode_apacket);
12851291 }
12861292
1293+ // This function will handle the av_frame_unref
1294+ // av_packet_unref is handled by caller
12871295 inline int decode_vpacket (AVCodecContext* pVCodecContext, const AVPacket* pVPacket,
12881296 AVFrame* pFrame, AVFrame* pLastFrame) {
12891297 // Return decoded output data (into a frame) from a decoder
12901298 // https://ffmpeg.org/doxygen/trunk/group__lavc__decoding.html#ga11e6542c4e66d3028668788a1a74217c
12911299 int response = avcodec_receive_frame (pVCodecContext, pFrame);
12921300
1293- #ifdef _DEBUG
1294- auto err = GetErrorStr (response);
1295- #endif
1296-
12971301 if (response == AVERROR (EAGAIN) || response == AVERROR_EOF) {
1302+ av_frame_unref (pFrame);
12981303 return response;
12991304 }
13001305
13011306 if (response < 0 ) {
13021307 av_frame_unref (pFrame);
1303-
13041308 return response;
13051309 }
13061310
1307- // videoPts = 0;
13081311 videoPts = static_cast <double >(pFrame->best_effort_timestamp );
13091312
13101313 if (pVPacket != nullptr ) {
@@ -1339,23 +1342,26 @@ class FFMpeg {
13391342 }
13401343#endif
13411344
1342- if (!bSeeking
1343- || (bSeeking && (videoClock >= seekingTargetPts))) {
1345+ // update laset frame by moving ref
1346+ if (!bSeeking || (bSeeking && (videoClock >= seekingTargetPts))) {
13441347 av_frame_unref (pLastFrame);
1345- av_frame_ref (pLastFrame, pFrame);
1348+ av_frame_move_ref (pLastFrame, pFrame);
13461349 }
13471350
13481351 av_frame_unref (pFrame);
13491352
13501353 return response;
13511354 }
13521355
1356+ // This function will handle the av_frame_unref
1357+ // av_packet_unref is handled by caller
13531358 // https://github.com/brookicv/FFMPEG-study/blob/master/FFmpeg-playAudio.cpp
13541359 inline int decode_apacket (AVCodecContext* pACodecContext, const AVPacket* pAPacket,
13551360 AVFrame* pFrame, AVFrame* pLastFrame) {
13561361 int response = avcodec_receive_frame (pACodecContext, pFrame);
13571362
13581363 if (response == AVERROR (EAGAIN) || response == AVERROR_EOF) {
1364+ av_frame_unref (pFrame);
13591365 return response;
13601366 }
13611367
@@ -1364,10 +1370,18 @@ class FFMpeg {
13641370 return response;
13651371 }
13661372
1373+ // frame to process
1374+ auto pBaseFrame = pFrame;
1375+
1376+ // a while loop is wrapped in, `av_buffersink_get_frame` to get filtered frame
13671377#ifdef AUDIO_TEMPO
1378+ pBaseFrame = pAFilterFrame;
13681379 response = av_buffersrc_add_frame_flags (buffersrc_ctx, pFrame, AV_BUFFERSRC_FLAG_KEEP_REF);
13691380
1370- if (response < 0 ) { return response; }
1381+ if (response < 0 ) {
1382+ av_frame_unref (pFrame);
1383+ return response;
1384+ }
13711385
13721386 while (true ) {
13731387 response = av_buffersink_get_frame (buffersink_ctx, pAFilterFrame);
@@ -1376,8 +1390,8 @@ class FFMpeg {
13761390 }
13771391
13781392 if (response < 0 ) {
1379- av_frame_unref (pFrame);
13801393 av_frame_unref (pAFilterFrame);
1394+ av_frame_unref (pFrame);
13811395 }
13821396#endif // AUDIO_TEMPO
13831397
@@ -1390,12 +1404,6 @@ class FFMpeg {
13901404#endif
13911405 }
13921406
1393- #ifdef AUDIO_TEMPO
1394- auto pBaseFrame = pAFilterFrame;
1395- #else
1396- auto pBaseFrame = pFrame;
1397- #endif // AUDIO_TEMPO
1398-
13991407 // update context to avoid crash
14001408 if (bUpdateSwr) {
14011409 init_SwrContext (&pBaseFrame->ch_layout ,
@@ -1421,15 +1429,23 @@ class FFMpeg {
14211429 audioPts = audioClock;
14221430 audioClock += static_cast <double >(audioSize) / (static_cast <double >(pcm_bytes) * static_cast <double >(pACodecContext->sample_rate ));
14231431
1432+ #ifdef AUDIO_TEMPO
1433+ av_frame_unref (pAFilterFrame);
1434+ #endif // AUDIO_TEMPO
1435+
1436+ av_frame_unref (pFrame);
1437+
14241438 return audioSize;
14251439
14261440#ifdef AUDIO_TEMPO
14271441 }
14281442
1429- av_frame_unref (pAFrame);
1443+ av_frame_unref (pAFilterFrame);
1444+ #endif // AUDIO_TEMPO
1445+
1446+ av_frame_unref (pFrame);
14301447
14311448 return -1 ;
1432- #endif // AUDIO_TEMPO
14331449 }
14341450
14351451 // ------------------------------------
0 commit comments