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) {