};
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;
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) {
return -ENOMEM;
}
+ priv->ctx_out->flags |= AVFMT_FLAG_NONBLOCK;
+
c = avcodec_find_encoder(out->audio_codec);
if (!c)
return -EINVAL;
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;
if (av_frame_get_buffer(priv->oframe, 1) < 0)
return -ENOMEM;
+ priv->diff_out = 1000000LL * 1024 / priv->codec_out->sample_rate;
return 0;
}
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;
}
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) {