From 828631029ea5791aaba8f718c1af63fab3a4d1b4 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Mon, 10 Apr 2023 16:15:28 +0800 Subject: [PATCH] tmp --- simp.h | 1 + simp_ffmpeg.h | 4 ++ simp_ffmpeg_output.c | 134 +++++++++++++++++++++++++++++++++---------- 3 files changed, 108 insertions(+), 31 deletions(-) diff --git a/simp.h b/simp.h index 8e2dba9..7b571bd 100644 --- a/simp.h +++ b/simp.h @@ -10,6 +10,7 @@ #include "libavfilter/avfilter.h" #include "libavfilter/buffersrc.h" #include "libavfilter/buffersink.h" +#include "libavutil/audio_fifo.h" typedef struct simp_avio_s simp_avio_t; typedef struct simp_avio_ops_s simp_avio_ops_t; diff --git a/simp_ffmpeg.h b/simp_ffmpeg.h index c200b8d..9ebbe0d 100644 --- a/simp_ffmpeg.h +++ b/simp_ffmpeg.h @@ -8,11 +8,15 @@ typedef struct { AVCodecContext* vdec_ctx; AVCodecContext* adec_ctx; + AVAudioFifo* afifo; + int vidx; int aidx; AVFrame* vframe; AVFrame* aframe; + AVPacket* vpkt; + AVPacket* apkt; } simp_ffmpeg_t; diff --git a/simp_ffmpeg_output.c b/simp_ffmpeg_output.c index db14f49..cefe9f7 100644 --- a/simp_ffmpeg_output.c +++ b/simp_ffmpeg_output.c @@ -26,7 +26,7 @@ static int _video_init(simp_ffmpeg_t* priv) priv->vdec_ctx->width = 1920; priv->vdec_ctx->height = 1080; priv->vdec_ctx->time_base = (AVRational){1, 25}; - priv->vdec_ctx->gop_size = 20; + priv->vdec_ctx->gop_size = 30; priv->vdec_ctx->max_b_frames = 2; priv->vdec_ctx->pix_fmt = AV_PIX_FMT_YUV420P; s->time_base = priv->vdec_ctx->time_base; @@ -40,6 +40,10 @@ static int _video_init(simp_ffmpeg_t* priv) return ret; } + priv->vpkt = av_packet_alloc(); + if (!priv->vpkt) + return -ENOMEM; + return 0; } @@ -81,6 +85,25 @@ static int _audio_init(simp_ffmpeg_t* priv) return ret; } + priv->afifo = av_audio_fifo_alloc(AV_SAMPLE_FMT_FLTP, 2, 1024); + if (!priv->afifo) + return -ENOMEM; + + priv->apkt = av_packet_alloc(); + if (!priv->apkt) + return -ENOMEM; + + priv->aframe = av_frame_alloc(); + if (!priv->aframe) + return -ENOMEM; + + priv->aframe->format = AV_SAMPLE_FMT_FLTP; + priv->aframe->channels = 2; + priv->aframe->nb_samples = 1024; + + if (av_frame_get_buffer(priv->aframe, 1) < 0) + return -ENOMEM; + return 0; } @@ -133,6 +156,9 @@ error: if (priv->adec_ctx) avcodec_close(priv->adec_ctx); + if (priv->afifo) + av_audio_fifo_free(priv->afifo); + free(priv); return ret; } @@ -146,7 +172,7 @@ static int _ffmpeg_close(simp_avio_t* io) io->exit = 1; while (-1 != io->tid) { pthread_cond_signal(&io->cond); - pthread_cond_signal(&io->cond); + pthread_cond_wait(&io->cond, &io->mutex); } pthread_mutex_unlock(&io->mutex); @@ -162,6 +188,9 @@ static int _ffmpeg_close(simp_avio_t* io) if (priv->adec_ctx) avcodec_close(priv->adec_ctx); + if (priv->afifo) + av_audio_fifo_free(priv->afifo); + if (priv->vframe) av_frame_free(&priv->vframe); @@ -175,38 +204,35 @@ static int _ffmpeg_close(simp_avio_t* io) return 0; } -static int __ffmpeg_decode(simp_avio_t* io, AVCodecContext* dec_ctx, AVPacket* pkt, AVFrame* frame, scf_list_t* h) +static int __ffmpeg_encode(simp_avio_t* io, AVCodecContext* c, AVPacket* pkt, AVFrame* frame) { - int ret = avcodec_send_packet(dec_ctx, pkt); + simp_ffmpeg_t* priv = io->priv; + simp_frame_t* f; + AVStream* s; + + int ret = avcodec_send_frame(c, frame); if (ret < 0) { - scf_loge("avcodec_send_packet error, ret: %s\n", av_err2str(ret)); + scf_loge("avcodec_send_frame error, ret: %s\n", av_err2str(ret)); return ret; } while (ret >= 0) { - ret = avcodec_receive_frame(dec_ctx, frame); + ret = avcodec_receive_packet(c, pkt); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) break; else if (ret < 0) { - printf("avcodec_receive_frame error, ret: %d, %s\n", ret, av_err2str(ret)); + scf_loge("avcodec_receive_packet error, ret: %s\n", av_err2str(ret)); return ret; } - frame->pts = frame->best_effort_timestamp; - - simp_frame_t* f = simp_frame_alloc(); - if (!f) - return -ENOMEM; + ret = av_write_frame(priv->fmt_ctx, pkt); + av_packet_unref(pkt); - ret = av_frame_copy(f->frame, frame); - if (ret < 0) + if (ret < 0) { + scf_loge("av_write_frame error, ret: %s\n", av_err2str(ret)); return ret; - - pthread_mutex_lock(&io->mutex); - scf_list_add_tail(h, &f->list); - pthread_cond_signal(&io->cond); - pthread_mutex_unlock(&io->mutex); + } } return 0; @@ -218,25 +244,71 @@ static void* __ffmpeg_run(void* arg) simp_ffmpeg_t* priv = io->priv; AVPacket* pkt = NULL; - simp_frame_t* vf; - simp_frame_t* af; - scf_list_t* vl; - scf_list_t* al; - - pkt = av_packet_alloc(); - if (!pkt) - goto end; + simp_frame_t* f; + scf_list_t* l; while (!io->exit) { pthread_mutex_lock(&io->mutex); - pthread_mutex_unlock(&io->mutex); + if (!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_unlock(&io->mutex); + + int ret = __ffmpeg_encode(io, priv->vdec_ctx, priv->vpkt, f->frame); + + simp_frame_free(f); + f = NULL; + + if (ret < 0) { + io->error = ret; + goto end; + } + + } else if (!scf_list_empty(&io->aout)) { + l = scf_list_head(&io->aout); + f = scf_list_data(l, simp_frame_t, list); + + scf_list_del(&f->list); + pthread_mutex_unlock(&io->mutex); + + int ret = av_audio_fifo_write(priv->afifo, (void**)f->frame->data, f->frame->nb_samples); + + simp_frame_free(f); + f = NULL; + + if (ret < 0) { + io->error = ret; + goto end; + } + + while (av_audio_fifo_size(priv->afifo) >= 1024) { + + ret = av_audio_fifo_read(priv->afifo, (void**)priv->aframe->data, 1024); + if (ret < 0) { + io->error = ret; + goto end; + + } else if (1024 != ret) { + io->error = -1; + goto end; + } + + ret = __ffmpeg_encode(io, priv->adec_ctx, priv->apkt, priv->aframe); + if (ret < 0) { + io->error = ret; + goto end; + } + } + } else { + pthread_cond_wait(&io->cond, &io->mutex); + pthread_mutex_unlock(&io->mutex); + } } end: - if (pkt) - av_packet_free(&pkt); - pthread_mutex_lock(&io->mutex); io->tid = -1; pthread_cond_signal(&io->cond); -- 2.25.1