ffmpeg alsa output
authoryu.dongliang <18588496441@163.com>
Sat, 15 Apr 2023 05:13:34 +0000 (13:13 +0800)
committeryu.dongliang <18588496441@163.com>
Sat, 15 Apr 2023 05:13:38 +0000 (13:13 +0800)
simp.h
simp_ffmpeg_alsa.c

diff --git a/simp.h b/simp.h
index 372d95f910f687ce54f5a85980d03a54fd2c6543..bf7c56db8ad5cd5a4a1772be64dc1aac0041e71d 100644 (file)
--- a/simp.h
+++ b/simp.h
@@ -29,57 +29,59 @@ struct simp_frame_s
 };
 
 typedef struct {
-       AVFormatContext*  fmt_ctx;
-       AVCodecContext*   vcodec_ctx;
-       AVCodecContext*   acodec_ctx;
+       AVFormatContext*     fmt_ctx;
+       AVCodecContext*      vcodec_ctx;
+       AVCodecContext*      acodec_ctx;
 
-       AVAudioFifo*      afifo;
+       AVAudioFifo*         afifo;
 
-       int               vidx;
-       int               aidx;
+       int                  vidx;
+       int                  aidx;
 
-       int               nb_samples;
+       int                  nb_samples;
 
-       AVFrame*          vframe;
-       AVFrame*          aframe;
-       AVPacket*         vpkt;
-       AVPacket*         apkt;
+       AVFrame*             vframe;
+       AVFrame*             aframe;
+       AVPacket*            vpkt;
+       AVPacket*            apkt;
 
 } simp_ffmpeg_t;
 
 typedef struct {
-       AVFormatContext*  ctx_in;
-       AVFormatContext*  ctx_out;
-       AVCodecContext*   codec_in;
-       AVCodecContext*   codec_out;
+       AVFormatContext*     ctx_in;
+       AVFormatContext*     ctx_out;
+       AVCodecContext*      codec_in;
+       AVCodecContext*      codec_out;
 
-       AVAudioFifo*      afifo;
+       AVAudioFifo*         afifo;
 
-       AVFilterContext*  obuffersrc_ctx;
-       AVFilterContext*  obuffersink_ctx;
-       AVFilterGraph*    ograph;
+       AVFilterContext*     obuffersrc_ctx;
+       AVFilterContext*     obuffersink_ctx;
+       AVFilterGraph*       ograph;
 
-       int               idx_in;
-       int               idx_out;
+       AVFrame*             iframe;
+       AVFrame*             oframe;
+       AVFrame*             fframe;
 
-       AVFrame*          iframe;
-       AVFrame*          oframe;
-       AVFrame*          fframe;
+       AVPacket*            ipkt;
+       AVPacket*            opkt;
 
-       AVPacket*         ipkt;
-       AVPacket*         opkt;
+       int64_t              prev_out;
+       int64_t              diff_out;
 
-       int               nb_samples;
+       int                  idx_in;
+       int                  idx_out;
 
+       int                  nb_samples;
 } simp_audio_t;
 
 struct  simp_avio_s
 {
        int                  refs;
 
+       int                  nb_vframes;
        scf_list_t           vin;
        scf_list_t           ain;
-       int                  nb_vframes;
 
        scf_list_t           vout;
        scf_list_t           aout;
index 794bf58fab3b569c5787bdc67e9506e3ed6bdba8..a8fccda646163cf37fd20d7917db48875713a02c 100644 (file)
@@ -103,7 +103,7 @@ static int _audio_input_init(simp_audio_t* priv, const char* path)
        if (!priv->ctx_in)
                return -ENOMEM;
 
-       priv->ctx_in->flags |= AVFMT_FLAG_NONBLOCK;
+//     priv->ctx_in->flags |= AVFMT_FLAG_NONBLOCK;
 
        int ret = avformat_open_input(&priv->ctx_in, path, in, NULL);
        if (ret < 0) {
@@ -167,6 +167,8 @@ static int _audio_output_init(simp_audio_t* priv, const char* path)
                return -ENOMEM;
        }
 
+       priv->ctx_out->flags |= AVFMT_FLAG_NONBLOCK;
+
        c = avcodec_find_encoder(out->audio_codec);
        if (!c)
                return -EINVAL;
@@ -183,7 +185,6 @@ static int _audio_output_init(simp_audio_t* priv, const char* path)
                return -ENOMEM;
 
        priv->codec_out->codec_id       = c->id;
-//     priv->codec_out->bit_rate       = 64 * 1024;
        priv->codec_out->sample_rate    = 44100;
        priv->codec_out->sample_fmt     = c->sample_fmts[0];
        priv->codec_out->channels       = 2;
@@ -235,6 +236,7 @@ static int _audio_output_init(simp_audio_t* priv, const char* path)
        if (av_frame_get_buffer(priv->oframe, 1) < 0)
                return -ENOMEM;
 
+       priv->diff_out = 1000000LL * 1024 / priv->codec_out->sample_rate;
        return 0;
 }
 
@@ -377,6 +379,7 @@ static int __output_audio(simp_avio_t* io, AVCodecContext* c, AVPacket* pkt, AVF
 
                        ret = av_audio_fifo_write(priv->afifo, (void**)priv->fframe->data, priv->fframe->nb_samples);
                        av_frame_unref(priv->fframe);
+
                        if (ret < 0)
                                return ret;
                }
@@ -415,15 +418,27 @@ static int __output_audio(simp_avio_t* io, AVCodecContext* c, AVPacket* pkt, AVF
                                return ret;
                        }
 
-                       pkt->stream_index = priv->idx_out;
+                       pkt->stream_index   = priv->idx_out;
+                       pkt->pts            = pkt->pts * av_q2d(c->time_base) / av_q2d(s->time_base);
+                       pkt->dts            = pkt->dts * av_q2d(c->time_base) / av_q2d(s->time_base);
+
+                       int64_t cur = gettime();
 
-                       pkt->pts = pkt->pts * av_q2d(c->time_base) / av_q2d(s->time_base);
-                       pkt->dts = pkt->dts * av_q2d(c->time_base) / av_q2d(s->time_base);
+                       if (priv->prev_out <= 0)
+                               priv->prev_out  = cur;
 
-                       scf_logw("idx: %d, pkt->stream_index: %d, pkt->pts: %ld, c->time_base: %d:%d, s->time_base: %d:%d\n",
-                                       priv->idx_out, pkt->stream_index, pkt->pts, c->time_base.num, c->time_base.den, s->time_base.num, s->time_base.den);
+                       int diff = priv->prev_out + priv->diff_out - cur;
+                       if (diff > 0)
+                               usleep(diff);
+
+                       priv->prev_out = cur;
 
                        ret = av_write_frame(priv->ctx_out, pkt);
+
+                       scf_logw("idx: %d, pkt->stream_index: %d, pkt->pts: %ld, c->time_base: %d:%d, s->time_base: %d:%d, diff: %d, %ld\n",
+                                       priv->idx_out, pkt->stream_index, pkt->pts, c->time_base.num, c->time_base.den, s->time_base.num, s->time_base.den,
+                                       diff, priv->diff_out);
+
                        av_packet_unref(pkt);
 
                        if (ret < 0) {