tmp
authoryu.dongliang <18588496441@163.com>
Mon, 10 Apr 2023 08:15:28 +0000 (16:15 +0800)
committeryu.dongliang <18588496441@163.com>
Mon, 10 Apr 2023 08:15:28 +0000 (16:15 +0800)
simp.h
simp_ffmpeg.h
simp_ffmpeg_output.c

diff --git a/simp.h b/simp.h
index 8e2dba9f99790ddd7444c7edf56c90c8f25affeb..7b571bd97e6c8360af6b6148455b1cf118b7bdad 100644 (file)
--- 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;
index c200b8d225651b61d3ea7770c44c55ae8f96328a..9ebbe0db66b51f5143c267e77d12773683d17e16 100644 (file)
@@ -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;
 
index db14f49f4475867def7a7db42cf534f82534dcdb..cefe9f7e42a8021c8b885b31ac5dcc8dcc552b57 100644 (file)
@@ -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);