From 85984532a9a033b87bcc54e5b9aa28c8528438ec Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Tue, 11 Apr 2023 21:41:15 +0800 Subject: [PATCH] free memory --- main.c | 2 +- simp.c | 5 ++ simp.h | 3 +- simp_ffmpeg_output.c | 106 +++++++++++++++------------ simp_filter.c | 165 ++++++++++++++++++++++++++++++++----------- 5 files changed, 192 insertions(+), 89 deletions(-) diff --git a/main.c b/main.c index f498219..a7d1d8e 100644 --- a/main.c +++ b/main.c @@ -55,7 +55,7 @@ int main(int argc, char* argv[]) sleep(1); } - simp_filter_close(f); + simp_filter_close(f, 1); printf("main quit ok\n"); return 0; diff --git a/simp.c b/simp.c index e114bfe..ca33005 100644 --- a/simp.c +++ b/simp.c @@ -93,6 +93,11 @@ int simp_avio_close(simp_avio_t* io) if (io->ops && io->ops->close) io->ops->close(io); + scf_list_clear(&io->vin, simp_frame_t, list, simp_frame_free); + scf_list_clear(&io->ain, simp_frame_t, list, simp_frame_free); + scf_list_clear(&io->vout, simp_frame_t, list, simp_frame_free); + scf_list_clear(&io->aout, simp_frame_t, list, simp_frame_free); + free(io); } return 0; diff --git a/simp.h b/simp.h index 6aa2bfa..3ced822 100644 --- a/simp.h +++ b/simp.h @@ -83,6 +83,7 @@ struct simp_filter_s int error; int exit; + int flush; pthread_t tid; pthread_mutex_t mutex; pthread_cond_t cond; @@ -107,7 +108,7 @@ int simp_avio_run (simp_avio_t* io); int simp_avio_stop (simp_avio_t* io); int simp_filter_open (simp_filter_t** pf); -int simp_filter_close (simp_filter_t* f); +int simp_filter_close (simp_filter_t* f, int flush); int simp_filter_run (simp_filter_t* f); int simp_filter_add_input (simp_filter_t* f, simp_avio_t* input); diff --git a/simp_ffmpeg_output.c b/simp_ffmpeg_output.c index 549226d..db36f5c 100644 --- a/simp_ffmpeg_output.c +++ b/simp_ffmpeg_output.c @@ -230,6 +230,12 @@ static int _ffmpeg_output_close(simp_avio_t* io) if (priv->aframe) av_frame_free(&priv->aframe); + if (priv->vpkt) + av_packet_free(&priv->vpkt); + + if (priv->apkt) + av_packet_free(&priv->apkt); + free(priv); } } @@ -299,6 +305,7 @@ static void* __ffmpeg_output_run(void* arg) ret = avio_open(&priv->fmt_ctx->pb, priv->fmt_ctx->url, AVIO_FLAG_WRITE); if (ret < 0) { scf_loge("Could not open output file '%s'", priv->fmt_ctx->url); + io->error = ret; goto end; } } @@ -306,6 +313,7 @@ static void* __ffmpeg_output_run(void* arg) ret = avformat_write_header(priv->fmt_ctx, NULL); if (ret < 0) { scf_loge("avformat_write_header error, ret: %s\n", av_err2str(ret)); + io->error = ret; goto end; } @@ -381,74 +389,80 @@ static void* __ffmpeg_output_run(void* arg) } - if (io->flush) { - pthread_mutex_lock(&io->mutex); - while(!scf_list_empty(&io->vout)) { - l = scf_list_head(&io->vout); - f = scf_list_data(l, simp_frame_t, list); - - scf_list_del(&f->list); + pthread_mutex_lock(&io->mutex); + while(!scf_list_empty(&io->vout)) { + l = scf_list_head(&io->vout); + f = scf_list_data(l, simp_frame_t, list); - scf_logd("priv->vidx: %d, frame->pts: %ld\n", priv->vidx, f->frame->pts); + scf_list_del(&f->list); - if (0 == io->error) { + scf_logd("priv->vidx: %d, frame->pts: %ld\n", priv->vidx, f->frame->pts); - ret = __ffmpeg_encode(io, priv->vcodec_ctx, priv->vpkt, f->frame, priv->vidx); - if (ret < 0) - scf_loge("ret: %d, frame->pts: %ld\n", ret, f->frame->pts); + if (0 == io->error && io->flush) { - io->error = ret; - } + ret = __ffmpeg_encode(io, priv->vcodec_ctx, priv->vpkt, f->frame, priv->vidx); + if (ret < 0) + scf_loge("ret: %d, frame->pts: %ld\n", ret, f->frame->pts); - simp_frame_free(f); - f = NULL; + io->error = ret; } - while (!scf_list_empty(&io->aout)) { - l = scf_list_head(&io->aout); - f = scf_list_data(l, simp_frame_t, list); + simp_frame_free(f); + f = NULL; + } - scf_list_del(&f->list); + while (!scf_list_empty(&io->aout)) { + l = scf_list_head(&io->aout); + f = scf_list_data(l, simp_frame_t, list); - if (0 == io->error) { - ret = av_audio_fifo_write(priv->afifo, (void**)f->frame->data, f->frame->nb_samples); - if (ret < 0) - scf_loge("ret: %d\n", ret); + scf_list_del(&f->list); - io->error = ret; - } + if (0 == io->error && io->flush) { - simp_frame_free(f); - f = NULL; + ret = av_audio_fifo_write(priv->afifo, (void**)f->frame->data, f->frame->nb_samples); + if (ret < 0) + scf_loge("ret: %d\n", ret); + + io->error = ret; } - while (av_audio_fifo_size(priv->afifo) > 0) { + simp_frame_free(f); + f = NULL; + } - if (0 == io->error) { - ret = av_audio_fifo_read(priv->afifo, (void**)priv->aframe->data, 1024); - if (ret < 0) { - scf_loge("ret: %d\n", ret); - io->error = ret; - break; - } + while (av_audio_fifo_size(priv->afifo) > 0) { - priv->nb_samples += priv->aframe->nb_samples; - priv->aframe->pts = priv->nb_samples; + if (0 == io->error && io->flush) { - scf_logd("aframe->pts: %ld\n", priv->aframe->pts); + ret = av_audio_fifo_read(priv->afifo, (void**)priv->aframe->data, 1024); + if (ret < 0) { + scf_loge("ret: %d\n", ret); + io->error = ret; + break; + } - ret = __ffmpeg_encode(io, priv->acodec_ctx, priv->apkt, priv->aframe, priv->aidx); - if (ret < 0) { - scf_loge("ret: %d\n", ret); - io->error = ret; - break; - } + priv->nb_samples += priv->aframe->nb_samples; + priv->aframe->pts = priv->nb_samples; + + scf_logd("aframe->pts: %ld\n", priv->aframe->pts); + + ret = __ffmpeg_encode(io, priv->acodec_ctx, priv->apkt, priv->aframe, priv->aidx); + if (ret < 0) { + scf_loge("ret: %d\n", ret); + io->error = ret; + break; } } - pthread_mutex_unlock(&io->mutex); } + pthread_mutex_unlock(&io->mutex); end: + ret = av_write_trailer(priv->fmt_ctx); + if (ret < 0) { + io->error = ret; + scf_loge("av_write_trailer error, ret: %s\n", av_err2str(ret)); + } + pthread_mutex_lock(&io->mutex); io->tid = -1; pthread_cond_signal(&io->cond); diff --git a/simp_filter.c b/simp_filter.c index 6501430..f857dde 100644 --- a/simp_filter.c +++ b/simp_filter.c @@ -205,10 +205,58 @@ int simp_filter_open(simp_filter_t** pf) return 0; } -int simp_filter_close(simp_filter_t* f) +int simp_filter_close(simp_filter_t* f, int flush) { - scf_loge("\n"); - return -1; + simp_avio_t* io; + scf_list_t* l; + + if (!f) + return -EINVAL; + + pthread_mutex_lock(&f->mutex); + if (flush) + f->flush = 1; + else + f->exit = 1; + + while (-1 != f->tid) { + pthread_cond_signal(&f->cond); + pthread_cond_wait(&f->cond, &f->mutex); + } + pthread_mutex_unlock(&f->mutex); + + avfilter_graph_free(&f->vgraph); + avfilter_graph_free(&f->agraph); + + f->abuffersink_ctx = NULL; + f->vbuffersink_ctx = NULL; + + av_frame_free(&f->vframe); + av_frame_free(&f->aframe); + + for (l = scf_list_head(&f->inputs); l != scf_list_sentinel(&f->inputs); ) { + io = scf_list_data(l, simp_avio_t, list); + l = scf_list_next(l); + + scf_list_del(&io->list); + + io->abuffersrc_ctx = NULL; + io->vbuffersrc_ctx = NULL; + + simp_avio_close(io); + io = NULL; + } + + for (l = scf_list_head(&f->outputs); l != scf_list_sentinel(&f->outputs); ) { + io = scf_list_data(l, simp_avio_t, list); + l = scf_list_next(l); + + scf_list_del(&io->list); + simp_avio_close(io); + io = NULL; + } + + return 0; } static int _filter_add_video(simp_avio_t* io) @@ -305,9 +353,9 @@ static void* __filter_run(void* arg) goto error; } + int flushed = 0; + while (!f->exit) { - int vn = 0; - int an = 0; usleep(500 * 1000); @@ -317,19 +365,43 @@ static void* __filter_run(void* arg) if (io->start_time == 0) io->start_time = gettime(); + if (f->flush) + simp_avio_stop(io); + if (io->vopen) { f->error = _filter_add_video(io); if (f->error < 0) goto error; + + if (f->flush) { + flushed++; + + pthread_mutex_lock(&io->mutex); + if (scf_list_empty(&io->vin)) + flushed--; + pthread_mutex_unlock(&io->mutex); + } } if (io->aopen) { f->error = _filter_add_audio(io); if (f->error < 0) goto error; + + if (f->flush) { + flushed++; + + pthread_mutex_lock(&io->mutex); + if (scf_list_empty(&io->ain)) + flushed--; + pthread_mutex_unlock(&io->mutex); + } } } + if (f->flush && 0 == flushed) + f->exit = 1; + while (1) { int ret = av_buffersink_get_frame(f->vbuffersink_ctx, f->vframe); @@ -361,28 +433,30 @@ static void* __filter_run(void* arg) for (l = scf_list_head(&f->outputs); l != scf_list_sentinel(&f->outputs); l = scf_list_next(l)) { io = scf_list_data(l, simp_avio_t, list); - vf = calloc(1, sizeof(simp_frame_t)); - if (!vf) { - f->error = -ENOMEM; - goto error; - } + if (io->vopen) { + vf = calloc(1, sizeof(simp_frame_t)); + if (!vf) { + f->error = -ENOMEM; + goto error; + } - vf->frame = av_frame_clone(f->vframe); - if (!vf->frame) { - simp_frame_free(vf); - vf = NULL; + vf->frame = av_frame_clone(f->vframe); + if (!vf->frame) { + simp_frame_free(vf); + vf = NULL; - f->error = -ENOMEM; - goto error; - } + f->error = -ENOMEM; + goto error; + } - scf_logd("vf->frame->pts: %ld\n", vf->frame->pts); + scf_logd("vf->frame->pts: %ld\n", vf->frame->pts); - pthread_mutex_lock(&io->mutex); - scf_list_add_tail(&io->vout, &vf->list); - pthread_cond_signal(&io->cond); - pthread_mutex_unlock(&io->mutex); - vf = NULL; + pthread_mutex_lock(&io->mutex); + scf_list_add_tail(&io->vout, &vf->list); + pthread_cond_signal(&io->cond); + pthread_mutex_unlock(&io->mutex); + vf = NULL; + } } av_frame_unref(f->vframe); @@ -403,28 +477,33 @@ static void* __filter_run(void* arg) for (l = scf_list_head(&f->outputs); l != scf_list_sentinel(&f->outputs); l = scf_list_next(l)) { io = scf_list_data(l, simp_avio_t, list); - af = calloc(1, sizeof(simp_frame_t)); - if (!af) { - f->error = -ENOMEM; - goto error; - } + if (io->aopen) { + af = calloc(1, sizeof(simp_frame_t)); + if (!af) { + f->error = -ENOMEM; + goto error; + } - af->frame = av_frame_clone(f->aframe); - if (!af->frame) { - simp_frame_free(af); - af = NULL; + af->frame = av_frame_clone(f->aframe); + if (!af->frame) { + simp_frame_free(af); + af = NULL; - f->error = -ENOMEM; - goto error; - } + f->error = -ENOMEM; + goto error; + } + + scf_logd("af->frame->pts: %ld\n", af->frame->pts); - scf_logd("af->frame->pts: %ld\n", af->frame->pts); + pthread_mutex_lock(&io->mutex); + scf_list_add_tail(&io->aout, &af->list); + pthread_cond_signal(&io->cond); + pthread_mutex_unlock(&io->mutex); + af = NULL; + } - pthread_mutex_lock(&io->mutex); - scf_list_add_tail(&io->aout, &af->list); - pthread_cond_signal(&io->cond); - pthread_mutex_unlock(&io->mutex); - af = NULL; + if (f->flush) + io->flush = 1; } av_frame_unref(f->aframe); @@ -432,6 +511,10 @@ static void* __filter_run(void* arg) } error: + pthread_mutex_lock(&f->mutex); + f->tid = -1; + pthread_cond_signal(&f->cond); + pthread_mutex_unlock(&f->mutex); return NULL; } -- 2.25.1