#include"simp_ffmpeg.h"
#include"scf_def.h"
+static int _output_filter_init(simp_audio_t* priv)
+{
+ char args[512];
+ int ret = 0;
+
+ const AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
+ const AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
+
+ AVFilterInOut *outputs = NULL;
+ AVFilterInOut *inputs = NULL;
+
+ const char *afilters_descr = "[in]aresample=44100[out]";
+
+ priv->ograph = avfilter_graph_alloc();
+ if (!priv->ograph) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ snprintf(args, sizeof(args),
+ "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%#x",
+ 1, 44100, 44100,
+ av_get_sample_fmt_name(AV_SAMPLE_FMT_FLTP),
+ AV_CH_LAYOUT_STEREO);
+
+ printf("%s\n", args);
+
+ ret = avfilter_graph_create_filter(&priv->obuffersrc_ctx, abuffersrc, "in", args, NULL, priv->ograph);
+ if (ret < 0)
+ goto end;
+
+ outputs = avfilter_inout_alloc();
+ if (!outputs) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ outputs->name = av_strdup("in");
+ outputs->filter_ctx = priv->obuffersrc_ctx;
+ outputs->pad_idx = 0;
+ outputs->next = NULL;
+
+ const enum AVSampleFormat sample_fmts[] = {priv->codec_out->sample_fmt, -1};
+ const int sample_rates[] = {priv->codec_out->sample_rate, -1};
+ const int64_t layouts[] = {priv->codec_out->channel_layout, -1};
+
+ ret = avfilter_graph_create_filter(&priv->obuffersink_ctx, abuffersink, "out", NULL, NULL, priv->ograph);
+ if (ret < 0)
+ goto end;
+
+ inputs = avfilter_inout_alloc();
+ if (!inputs) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ inputs->name = av_strdup("out");
+ inputs->filter_ctx = priv->obuffersink_ctx;
+ inputs->pad_idx = 0;
+ inputs->next = NULL;
+
+ ret = av_opt_set_int_list(priv->obuffersink_ctx, "sample_fmts", sample_fmts, -1, AV_OPT_SEARCH_CHILDREN);
+ if (ret < 0)
+ goto end;
+
+ ret = av_opt_set_int_list(priv->obuffersink_ctx, "channel_layouts", layouts, -1, AV_OPT_SEARCH_CHILDREN);
+ if (ret < 0)
+ goto end;
+
+ ret = av_opt_set_int_list(priv->obuffersink_ctx, "sample_rates", sample_rates, -1, AV_OPT_SEARCH_CHILDREN);
+ if (ret < 0)
+ goto end;
+
+ if ((ret = avfilter_graph_parse_ptr(priv->ograph, afilters_descr, &inputs, &outputs, NULL)) < 0) {
+ scf_loge("\n");
+ goto end;
+ }
+
+ if ((ret = avfilter_graph_config(priv->ograph, NULL)) < 0) {
+ scf_loge("\n");
+ goto end;
+ }
+
+end:
+ avfilter_inout_free(&inputs);
+ avfilter_inout_free(&outputs);
+ return ret;
+}
+
static int _audio_input_init(simp_audio_t* priv, const char* path)
{
AVInputFormat* in = av_find_input_format("alsa");
return ret;
}
+ ret = _output_filter_init(priv);
+ if (ret < 0) {
+ scf_loge("output filter init error, ret: %d, %s\n", ret, av_err2str(ret));
+ return ret;
+ }
+
priv->afifo = av_audio_fifo_alloc(priv->codec_out->sample_fmt, 2, 1024);
if (!priv->afifo)
return -ENOMEM;
+ priv->fframe = av_frame_alloc();
+ if (!priv->fframe)
+ return -ENOMEM;
+
priv->opkt = av_packet_alloc();
if (!priv->opkt)
return -ENOMEM;
if (priv->codec_out)
avcodec_close(priv->codec_out);
+ if (priv->ograph)
+ avfilter_graph_free(&priv->ograph);
+
if (priv->afifo)
av_audio_fifo_free(priv->afifo);
if (priv->oframe)
av_frame_free(&priv->oframe);
+ if (priv->fframe)
+ av_frame_free(&priv->fframe);
+
if (priv->ipkt)
av_packet_free(&priv->ipkt);
scf_list_del(&f->list);
pthread_mutex_unlock(&io->mutex);
- ret = av_audio_fifo_write(priv->afifo, (void**)f->frame->data, f->frame->nb_samples);
-
scf_logd("priv->aidx: %d, frame->pts: %ld, frame->nb_samples: %d, afifo->size: %d\n",
priv->aidx, f->frame->pts, f->frame->nb_samples, av_audio_fifo_size(priv->afifo));
+ ret = av_buffersrc_add_frame_flags(priv->obuffersrc_ctx, f->frame, AV_BUFFERSRC_FLAG_KEEP_REF);
simp_frame_free(f);
f = NULL;
-
if (ret < 0)
return ret;
+ while (1) {
+ ret = av_buffersink_get_frame(priv->obuffersink_ctx, priv->fframe);
+
+ if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
+ break;
+ } else if (ret < 0) {
+ scf_loge("av_buffersink_get_frame error, ret: %s\n", av_err2str(ret));
+ return ret;
+ }
+
+ 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;
+ }
+
} else {
pthread_mutex_unlock(&io->mutex);
}