From: yu.dongliang <18588496441@163.com>
Date: Sat, 15 Apr 2023 05:13:34 +0000 (+0800)
Subject: ffmpeg alsa output
X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=d623cfaf58202a5ab4f23e476198f2e9eef797ab;p=simplay.git

ffmpeg alsa output
---

diff --git a/simp.h b/simp.h
index 372d95f..bf7c56d 100644
--- 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;
diff --git a/simp_ffmpeg_alsa.c b/simp_ffmpeg_alsa.c
index 794bf58..a8fccda 100644
--- a/simp_ffmpeg_alsa.c
+++ b/simp_ffmpeg_alsa.c
@@ -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) {