Ejemplo n.º 1
0
AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms,
        enum AVSampleFormat sample_fmt, int size,
        uint64_t channel_layout, int packed)
{
    return avfilter_get_audio_buffer(link->dst->outputs[0], perms, sample_fmt,
                                     size, channel_layout, packed);
}
Ejemplo n.º 2
0
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
{
    AResampleContext *aresample  = inlink->dst->priv;
    AVFilterLink * const outlink = inlink->dst->outputs[0];
    int i,
        in_nb_samples            = insamplesref->audio->nb_samples,
        cached_nb_samples        = in_nb_samples + aresample->unconsumed_nb_samples,
        requested_out_nb_samples = aresample->ratio * cached_nb_samples,
        nb_channels              =
            av_get_channel_layout_nb_channels(inlink->channel_layout);

    if (cached_nb_samples > aresample->max_cached_nb_samples) {
        for (i = 0; i < nb_channels; i++) {
            aresample->cached_data[i]    =
                av_realloc(aresample->cached_data[i], cached_nb_samples * sizeof(int16_t));
            aresample->resampled_data[i] =
                av_realloc(aresample->resampled_data[i],
                           FFALIGN(sizeof(int16_t) * requested_out_nb_samples, 16));

            if (aresample->cached_data[i] == NULL || aresample->resampled_data[i] == NULL)
                return;
        }
        aresample->max_cached_nb_samples = cached_nb_samples;

        if (aresample->outsamplesref)
            avfilter_unref_buffer(aresample->outsamplesref);

        aresample->outsamplesref =
            avfilter_get_audio_buffer(outlink, AV_PERM_WRITE, requested_out_nb_samples);
        outlink->out_buf = aresample->outsamplesref;
    }

    avfilter_copy_buffer_ref_props(aresample->outsamplesref, insamplesref);
    aresample->outsamplesref->audio->sample_rate = outlink->sample_rate;
    aresample->outsamplesref->pts =
        av_rescale(outlink->sample_rate, insamplesref->pts, inlink->sample_rate);

    /* av_resample() works with planar audio buffers */
    if (!inlink->planar && nb_channels > 1) {
        int16_t *out[8];
        for (i = 0; i < nb_channels; i++)
            out[i] = aresample->cached_data[i] + aresample->unconsumed_nb_samples;

        deinterleave(out, (int16_t *)insamplesref->data[0],
                     nb_channels, in_nb_samples);
    } else {
        for (i = 0; i < nb_channels; i++)
            memcpy(aresample->cached_data[i] + aresample->unconsumed_nb_samples,
                   insamplesref->data[i],
                   in_nb_samples * sizeof(int16_t));
    }

    for (i = 0; i < nb_channels; i++) {
        int consumed_nb_samples;
        const int is_last = i+1 == nb_channels;

        aresample->outsamplesref->audio->nb_samples =
            av_resample(aresample->resample,
                        aresample->resampled_data[i], aresample->cached_data[i],
                        &consumed_nb_samples,
                        cached_nb_samples,
                        requested_out_nb_samples, is_last);

        /* move unconsumed data back to the beginning of the cache */
        aresample->unconsumed_nb_samples = cached_nb_samples - consumed_nb_samples;
        memmove(aresample->cached_data[i],
                aresample->cached_data[i] + consumed_nb_samples,
                aresample->unconsumed_nb_samples * sizeof(int16_t));
    }


    /* copy resampled data to the output samplesref */
    if (!inlink->planar && nb_channels > 1) {
        interleave((int16_t *)aresample->outsamplesref->data[0],
                   aresample->resampled_data,
                   nb_channels, aresample->outsamplesref->audio->nb_samples);
    } else {
        for (i = 0; i < nb_channels; i++)
            memcpy(aresample->outsamplesref->data[i], aresample->resampled_data[i],
                   aresample->outsamplesref->audio->nb_samples * sizeof(int16_t));
    }

    avfilter_filter_samples(outlink, avfilter_ref_buffer(aresample->outsamplesref, ~0));
    avfilter_unref_buffer(insamplesref);
}
Ejemplo n.º 3
0
static int init_buffers(AVFilterLink *inlink, int nb_samples)
{
    AConvertContext *aconvert = inlink->dst->priv;
    AVFilterLink * const outlink = inlink->dst->outputs[0];
    int i, packed_stride = 0;
    const unsigned
        packing_conv = inlink->planar != outlink->planar &&
                       aconvert->out_nb_channels != 1,
        format_conv  = inlink->format != outlink->format;
    int nb_channels  = aconvert->out_nb_channels;

    uninit(inlink->dst);
    aconvert->max_nb_samples = nb_samples;

    if (aconvert->convert_chlayout) {
        /* allocate buffer for storing intermediary mixing samplesref */
        uint8_t *data[8];
        int linesize[8];
        int nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout);

        if (av_samples_alloc(data, linesize, nb_channels, nb_samples,
                             inlink->format, inlink->planar, 16) < 0)
            goto fail_no_mem;
        aconvert->mix_samplesref =
            avfilter_get_audio_buffer_ref_from_arrays(data, linesize, AV_PERM_WRITE,
                                                      nb_samples, inlink->format,
                                                      outlink->channel_layout,
                                                      inlink->planar);
        if (!aconvert->mix_samplesref)
            goto fail_no_mem;
    }

    // if there's a format/packing conversion we need an audio_convert context
    if (format_conv || packing_conv) {
        aconvert->out_samplesref =
            avfilter_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
        if (!aconvert->out_samplesref)
            goto fail_no_mem;

        aconvert->in_strides [0] = av_get_bytes_per_sample(inlink ->format);
        aconvert->out_strides[0] = av_get_bytes_per_sample(outlink->format);

        aconvert->out_conv = aconvert->out_samplesref->data;
        if (aconvert->mix_samplesref)
            aconvert->in_conv = aconvert->mix_samplesref->data;

        if (packing_conv) {
            // packed -> planar
            if (outlink->planar == AVFILTER_PLANAR) {
                if (aconvert->mix_samplesref)
                    aconvert->packed_data[0] = aconvert->mix_samplesref->data[0];
                aconvert->in_conv         = aconvert->packed_data;
                packed_stride             = aconvert->in_strides[0];
                aconvert->in_strides[0]  *= nb_channels;
            // planar -> packed
            } else {
                aconvert->packed_data[0]  = aconvert->out_samplesref->data[0];
                aconvert->out_conv        = aconvert->packed_data;
                packed_stride             = aconvert->out_strides[0];
                aconvert->out_strides[0] *= nb_channels;
            }
        } else if (outlink->planar == AVFILTER_PACKED) {
            /* If there's no packing conversion, and the stream is packed
             * then we treat the entire stream as one big channel
             */
            nb_channels = 1;
        }

        for (i = 1; i < nb_channels; i++) {
            aconvert->packed_data[i] = aconvert->packed_data[i-1] + packed_stride;
            aconvert->in_strides[i]  = aconvert->in_strides[0];
            aconvert->out_strides[i] = aconvert->out_strides[0];
        }

        aconvert->audioconvert_ctx =
                av_audio_convert_alloc(outlink->format, nb_channels,
                                       inlink->format,  nb_channels, NULL, 0);
        if (!aconvert->audioconvert_ctx)
            goto fail_no_mem;
    }

    return 0;

fail_no_mem:
    av_log(inlink->dst, AV_LOG_ERROR, "Could not allocate memory.\n");
    return AVERROR(ENOMEM);
}
AVFilterBufferRef *avfilter_null_get_audio_buffer(AVFilterLink *link, int perms,
                                                  int nb_samples)
{
    return avfilter_get_audio_buffer(link->dst->outputs[0], perms, nb_samples);
}