X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Faf_aresample.c;h=2dcfd695b062411094c04e48bb3751f5d3fb25eb;hb=1bb547192f6e9bd28b55f1f11d43bcc216976ac7;hp=e400e1f0bbcfbc93cfaa1275992f7e23eb5985a8;hpb=7eb40d85f2258df31287dc7a0704cb35e356c077;p=ffmpeg diff --git a/libavfilter/af_aresample.c b/libavfilter/af_aresample.c index e400e1f0bbc..2dcfd695b06 100644 --- a/libavfilter/af_aresample.c +++ b/libavfilter/af_aresample.c @@ -24,8 +24,8 @@ * resampling audio filter */ -#include "libavutil/audioconvert.h" #include "libavutil/avstring.h" +#include "libavutil/channel_layout.h" #include "libavutil/opt.h" #include "libavutil/samplefmt.h" #include "libavutil/avassert.h" @@ -170,15 +170,17 @@ static int config_output(AVFilterLink *outlink) return 0; } -static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref) +static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *insamplesref) { AResampleContext *aresample = inlink->dst->priv; const int n_in = insamplesref->audio->nb_samples; - int n_out = n_in * aresample->ratio * 2 ; + int n_out = FFMAX(n_in * aresample->ratio * 2, 1); AVFilterLink *const outlink = inlink->dst->outputs[0]; AVFilterBufferRef *outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n_out); int ret; + if(!outsamplesref) + return AVERROR(ENOMEM); avfilter_copy_buffer_ref_props(outsamplesref, insamplesref); outsamplesref->format = outlink->format; @@ -189,11 +191,10 @@ static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref) int64_t inpts = av_rescale(insamplesref->pts, inlink->time_base.num * (int64_t)outlink->sample_rate * inlink->sample_rate, inlink->time_base.den); int64_t outpts= swr_next_pts(aresample->swr, inpts); aresample->next_pts = - outsamplesref->pts = (outpts + inlink->sample_rate/2) / inlink->sample_rate; + outsamplesref->pts = ROUNDED_DIV(outpts, inlink->sample_rate); } else { outsamplesref->pts = AV_NOPTS_VALUE; } - n_out = swr_convert(aresample->swr, outsamplesref->extended_data, n_out, (void *)insamplesref->extended_data, n_in); if (n_out <= 0) { @@ -204,7 +205,7 @@ static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref) outsamplesref->audio->nb_samples = n_out; - ret = ff_filter_samples(outlink, outsamplesref); + ret = ff_filter_frame(outlink, outsamplesref); aresample->req_fullfilled= 1; avfilter_unref_buffer(insamplesref); return ret; @@ -242,15 +243,36 @@ static int request_frame(AVFilterLink *outlink) if(aresample->next_pts != AV_NOPTS_VALUE) aresample->next_pts += av_rescale_q(n_out, (AVRational){1 ,outlink->sample_rate}, outlink->time_base); #else - outsamplesref->pts = (swr_next_pts(aresample->swr, INT64_MIN) + inlink->sample_rate/2) / inlink->sample_rate; + outsamplesref->pts = swr_next_pts(aresample->swr, INT64_MIN); + outsamplesref->pts = ROUNDED_DIV(outsamplesref->pts, inlink->sample_rate); #endif - ff_filter_samples(outlink, outsamplesref); + ff_filter_frame(outlink, outsamplesref); return 0; } return ret; } +static const AVFilterPad aresample_inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .filter_frame = filter_frame, + .min_perms = AV_PERM_READ, + }, + { NULL }, +}; + +static const AVFilterPad aresample_outputs[] = { + { + .name = "default", + .config_props = config_output, + .request_frame = request_frame, + .type = AVMEDIA_TYPE_AUDIO, + }, + { NULL }, +}; + AVFilter avfilter_af_aresample = { .name = "aresample", .description = NULL_IF_CONFIG_SMALL("Resample audio data."), @@ -258,15 +280,6 @@ AVFilter avfilter_af_aresample = { .uninit = uninit, .query_formats = query_formats, .priv_size = sizeof(AResampleContext), - - .inputs = (const AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_samples = filter_samples, - .min_perms = AV_PERM_READ, }, - { .name = NULL}}, - .outputs = (const AVFilterPad[]) {{ .name = "default", - .config_props = config_output, - .request_frame = request_frame, - .type = AVMEDIA_TYPE_AUDIO, }, - { .name = NULL}}, + .inputs = aresample_inputs, + .outputs = aresample_outputs, };