00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "libavutil/eval.h"
00028 #include "libavcodec/avcodec.h"
00029 #include "avfilter.h"
00030 #include "internal.h"
00031
00032 typedef struct {
00033 struct AVResampleContext *resample;
00034 int out_rate;
00035 double ratio;
00036 AVFilterBufferRef *outsamplesref;
00037 int unconsumed_nb_samples,
00038 max_cached_nb_samples;
00039 int16_t *cached_data[8],
00040 *resampled_data[8];
00041 } AResampleContext;
00042
00043 static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
00044 {
00045 AResampleContext *aresample = ctx->priv;
00046 int ret;
00047
00048 if (args) {
00049 if ((ret = ff_parse_sample_rate(&aresample->out_rate, args, ctx)) < 0)
00050 return ret;
00051 } else {
00052 aresample->out_rate = -1;
00053 }
00054
00055 return 0;
00056 }
00057
00058 static av_cold void uninit(AVFilterContext *ctx)
00059 {
00060 AResampleContext *aresample = ctx->priv;
00061 if (aresample->outsamplesref) {
00062 int nb_channels =
00063 av_get_channel_layout_nb_channels(
00064 aresample->outsamplesref->audio->channel_layout);
00065 avfilter_unref_buffer(aresample->outsamplesref);
00066 while (nb_channels--) {
00067 av_freep(&(aresample->cached_data[nb_channels]));
00068 av_freep(&(aresample->resampled_data[nb_channels]));
00069 }
00070 }
00071
00072 if (aresample->resample)
00073 av_resample_close(aresample->resample);
00074 }
00075
00076 static int config_output(AVFilterLink *outlink)
00077 {
00078 AVFilterContext *ctx = outlink->src;
00079 AVFilterLink *inlink = ctx->inputs[0];
00080 AResampleContext *aresample = ctx->priv;
00081
00082 if (aresample->out_rate == -1)
00083 aresample->out_rate = outlink->sample_rate;
00084 else
00085 outlink->sample_rate = aresample->out_rate;
00086 outlink->time_base = (AVRational) {1, aresample->out_rate};
00087
00088
00089 aresample->resample = av_resample_init(aresample->out_rate, inlink->sample_rate,
00090 16, 10, 0, 0.8);
00091
00092 aresample->ratio = (double)outlink->sample_rate / inlink->sample_rate;
00093
00094 av_log(ctx, AV_LOG_INFO, "r:%"PRId64"Hz -> r:%"PRId64"Hz\n",
00095 inlink->sample_rate, outlink->sample_rate);
00096 return 0;
00097 }
00098
00099 static int query_formats(AVFilterContext *ctx)
00100 {
00101 AVFilterFormats *formats = NULL;
00102
00103 avfilter_add_format(&formats, AV_SAMPLE_FMT_S16);
00104 if (!formats)
00105 return AVERROR(ENOMEM);
00106 avfilter_set_common_sample_formats(ctx, formats);
00107
00108 formats = avfilter_make_all_channel_layouts();
00109 if (!formats)
00110 return AVERROR(ENOMEM);
00111 avfilter_set_common_channel_layouts(ctx, formats);
00112
00113 formats = avfilter_make_all_packing_formats();
00114 if (!formats)
00115 return AVERROR(ENOMEM);
00116 avfilter_set_common_packing_formats(ctx, formats);
00117
00118 return 0;
00119 }
00120
00121 static void deinterleave(int16_t **outp, int16_t *in,
00122 int nb_channels, int nb_samples)
00123 {
00124 int16_t *out[8];
00125 memcpy(out, outp, nb_channels * sizeof(int16_t*));
00126
00127 switch (nb_channels) {
00128 case 2:
00129 while (nb_samples--) {
00130 *out[0]++ = *in++;
00131 *out[1]++ = *in++;
00132 }
00133 break;
00134 case 3:
00135 while (nb_samples--) {
00136 *out[0]++ = *in++;
00137 *out[1]++ = *in++;
00138 *out[2]++ = *in++;
00139 }
00140 break;
00141 case 4:
00142 while (nb_samples--) {
00143 *out[0]++ = *in++;
00144 *out[1]++ = *in++;
00145 *out[2]++ = *in++;
00146 *out[3]++ = *in++;
00147 }
00148 break;
00149 case 5:
00150 while (nb_samples--) {
00151 *out[0]++ = *in++;
00152 *out[1]++ = *in++;
00153 *out[2]++ = *in++;
00154 *out[3]++ = *in++;
00155 *out[4]++ = *in++;
00156 }
00157 break;
00158 case 6:
00159 while (nb_samples--) {
00160 *out[0]++ = *in++;
00161 *out[1]++ = *in++;
00162 *out[2]++ = *in++;
00163 *out[3]++ = *in++;
00164 *out[4]++ = *in++;
00165 *out[5]++ = *in++;
00166 }
00167 break;
00168 case 8:
00169 while (nb_samples--) {
00170 *out[0]++ = *in++;
00171 *out[1]++ = *in++;
00172 *out[2]++ = *in++;
00173 *out[3]++ = *in++;
00174 *out[4]++ = *in++;
00175 *out[5]++ = *in++;
00176 *out[6]++ = *in++;
00177 *out[7]++ = *in++;
00178 }
00179 break;
00180 }
00181 }
00182
00183 static void interleave(int16_t *out, int16_t **inp,
00184 int nb_channels, int nb_samples)
00185 {
00186 int16_t *in[8];
00187 memcpy(in, inp, nb_channels * sizeof(int16_t*));
00188
00189 switch (nb_channels) {
00190 case 2:
00191 while (nb_samples--) {
00192 *out++ = *in[0]++;
00193 *out++ = *in[1]++;
00194 }
00195 break;
00196 case 3:
00197 while (nb_samples--) {
00198 *out++ = *in[0]++;
00199 *out++ = *in[1]++;
00200 *out++ = *in[2]++;
00201 }
00202 break;
00203 case 4:
00204 while (nb_samples--) {
00205 *out++ = *in[0]++;
00206 *out++ = *in[1]++;
00207 *out++ = *in[2]++;
00208 *out++ = *in[3]++;
00209 }
00210 break;
00211 case 5:
00212 while (nb_samples--) {
00213 *out++ = *in[0]++;
00214 *out++ = *in[1]++;
00215 *out++ = *in[2]++;
00216 *out++ = *in[3]++;
00217 *out++ = *in[4]++;
00218 }
00219 break;
00220 case 6:
00221 while (nb_samples--) {
00222 *out++ = *in[0]++;
00223 *out++ = *in[1]++;
00224 *out++ = *in[2]++;
00225 *out++ = *in[3]++;
00226 *out++ = *in[4]++;
00227 *out++ = *in[5]++;
00228 }
00229 break;
00230 case 8:
00231 while (nb_samples--) {
00232 *out++ = *in[0]++;
00233 *out++ = *in[1]++;
00234 *out++ = *in[2]++;
00235 *out++ = *in[3]++;
00236 *out++ = *in[4]++;
00237 *out++ = *in[5]++;
00238 *out++ = *in[6]++;
00239 *out++ = *in[7]++;
00240 }
00241 break;
00242 }
00243 }
00244
00245 static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
00246 {
00247 AResampleContext *aresample = inlink->dst->priv;
00248 AVFilterLink * const outlink = inlink->dst->outputs[0];
00249 int i,
00250 in_nb_samples = insamplesref->audio->nb_samples,
00251 cached_nb_samples = in_nb_samples + aresample->unconsumed_nb_samples,
00252 requested_out_nb_samples = aresample->ratio * cached_nb_samples,
00253 nb_channels =
00254 av_get_channel_layout_nb_channels(inlink->channel_layout);
00255
00256 if (cached_nb_samples > aresample->max_cached_nb_samples) {
00257 for (i = 0; i < nb_channels; i++) {
00258 aresample->cached_data[i] =
00259 av_realloc(aresample->cached_data[i], cached_nb_samples * sizeof(int16_t));
00260 aresample->resampled_data[i] =
00261 av_realloc(aresample->resampled_data[i],
00262 FFALIGN(sizeof(int16_t) * requested_out_nb_samples, 16));
00263
00264 if (aresample->cached_data[i] == NULL || aresample->resampled_data[i] == NULL)
00265 return;
00266 }
00267 aresample->max_cached_nb_samples = cached_nb_samples;
00268
00269 if (aresample->outsamplesref)
00270 avfilter_unref_buffer(aresample->outsamplesref);
00271
00272 aresample->outsamplesref =
00273 avfilter_get_audio_buffer(outlink, AV_PERM_WRITE, requested_out_nb_samples);
00274 outlink->out_buf = aresample->outsamplesref;
00275 }
00276
00277 avfilter_copy_buffer_ref_props(aresample->outsamplesref, insamplesref);
00278 aresample->outsamplesref->audio->sample_rate = outlink->sample_rate;
00279 aresample->outsamplesref->pts =
00280 av_rescale(outlink->sample_rate, insamplesref->pts, inlink->sample_rate);
00281
00282
00283 if (!inlink->planar && nb_channels > 1) {
00284 int16_t *out[8];
00285 for (i = 0; i < nb_channels; i++)
00286 out[i] = aresample->cached_data[i] + aresample->unconsumed_nb_samples;
00287
00288 deinterleave(out, (int16_t *)insamplesref->data[0],
00289 nb_channels, in_nb_samples);
00290 } else {
00291 for (i = 0; i < nb_channels; i++)
00292 memcpy(aresample->cached_data[i] + aresample->unconsumed_nb_samples,
00293 insamplesref->data[i],
00294 in_nb_samples * sizeof(int16_t));
00295 }
00296
00297 for (i = 0; i < nb_channels; i++) {
00298 int consumed_nb_samples;
00299 const int is_last = i+1 == nb_channels;
00300
00301 aresample->outsamplesref->audio->nb_samples =
00302 av_resample(aresample->resample,
00303 aresample->resampled_data[i], aresample->cached_data[i],
00304 &consumed_nb_samples,
00305 cached_nb_samples,
00306 requested_out_nb_samples, is_last);
00307
00308
00309 aresample->unconsumed_nb_samples = cached_nb_samples - consumed_nb_samples;
00310 memmove(aresample->cached_data[i],
00311 aresample->cached_data[i] + consumed_nb_samples,
00312 aresample->unconsumed_nb_samples * sizeof(int16_t));
00313 }
00314
00315
00316
00317 if (!inlink->planar && nb_channels > 1) {
00318 interleave((int16_t *)aresample->outsamplesref->data[0],
00319 aresample->resampled_data,
00320 nb_channels, aresample->outsamplesref->audio->nb_samples);
00321 } else {
00322 for (i = 0; i < nb_channels; i++)
00323 memcpy(aresample->outsamplesref->data[i], aresample->resampled_data[i],
00324 aresample->outsamplesref->audio->nb_samples * sizeof(int16_t));
00325 }
00326
00327 avfilter_filter_samples(outlink, avfilter_ref_buffer(aresample->outsamplesref, ~0));
00328 avfilter_unref_buffer(insamplesref);
00329 }
00330
00331 AVFilter avfilter_af_aresample = {
00332 .name = "aresample",
00333 .description = NULL_IF_CONFIG_SMALL("Resample audio data."),
00334 .init = init,
00335 .uninit = uninit,
00336 .query_formats = query_formats,
00337 .priv_size = sizeof(AResampleContext),
00338
00339 .inputs = (const AVFilterPad[]) {{ .name = "default",
00340 .type = AVMEDIA_TYPE_AUDIO,
00341 .filter_samples = filter_samples,
00342 .min_perms = AV_PERM_READ, },
00343 { .name = NULL}},
00344 .outputs = (const AVFilterPad[]) {{ .name = "default",
00345 .config_props = config_output,
00346 .type = AVMEDIA_TYPE_AUDIO, },
00347 { .name = NULL}},
00348 };