AVFilterBufferRef *ff_default_get_audio_buffer(AVFilterLink *link, int perms, int nb_samples) { AVFilterBufferRef *samplesref = NULL; uint8_t **data; int planar = av_sample_fmt_is_planar(link->format); int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout); int planes = planar ? nb_channels : 1; int linesize; if (!(data = av_mallocz(sizeof(*data) * planes))) goto fail; if (av_samples_alloc(data, &linesize, nb_channels, nb_samples, link->format, 0) < 0) goto fail; samplesref = avfilter_get_audio_buffer_ref_from_arrays(data, linesize, perms, nb_samples, link->format, link->channel_layout); if (!samplesref) goto fail; av_freep(&data); fail: if (data) av_freep(&data[0]); av_freep(&data); return samplesref; }
AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms, enum AVSampleFormat sample_fmt, int nb_samples, int64_t channel_layout, int planar) { AVFilterBufferRef *samplesref = NULL; int linesize[8]; uint8_t *data[8]; int nb_channels = av_get_channel_layout_nb_channels(channel_layout); /* Calculate total buffer size, round to multiple of 16 to be SIMD friendly */ if (av_samples_alloc(data, linesize, nb_channels, nb_samples, sample_fmt, planar, 16) < 0) return NULL; samplesref = avfilter_get_audio_buffer_ref_from_arrays(data, linesize, perms, nb_samples, sample_fmt, channel_layout, planar); if (!samplesref) { av_free(data[0]); return NULL; } return samplesref; }
AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame, int perms) { AVFilterBufferRef *picref = avfilter_get_audio_buffer_ref_from_arrays((uint8_t **)frame->data, frame->linesize[0], perms, frame->nb_samples, frame->format, av_frame_get_channel_layout(frame)); if (!picref) return NULL; avfilter_copy_frame_props(picref, frame); return picref; }
static int compat_read(AVFilterContext *ctx, AVFilterBufferRef **pbuf, int nb_samples) { AVFilterBufferRef *buf; AVFrame *frame; int ret; if (!pbuf) return ff_poll_frame(ctx->inputs[0]); frame = av_frame_alloc(); if (!frame) return AVERROR(ENOMEM); if (!nb_samples) ret = av_buffersink_get_frame(ctx, frame); else ret = av_buffersink_get_samples(ctx, frame, nb_samples); if (ret < 0) goto fail; if (ctx->inputs[0]->type == AVMEDIA_TYPE_VIDEO) { buf = avfilter_get_video_buffer_ref_from_arrays(frame->data, frame->linesize, AV_PERM_READ, frame->width, frame->height, frame->format); } else { buf = avfilter_get_audio_buffer_ref_from_arrays(frame->extended_data, frame->linesize[0], AV_PERM_READ, frame->nb_samples, frame->format, frame->channel_layout); } if (!buf) { ret = AVERROR(ENOMEM); goto fail; } avfilter_copy_frame_props(buf, frame); buf->buf->priv = frame; buf->buf->free = compat_free_buffer; *pbuf = buf; return 0; fail: av_frame_free(&frame); return ret; }
AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame, int perms) { AVFilterBufferRef *samplesref = avfilter_get_audio_buffer_ref_from_arrays((uint8_t **)frame->data, frame->linesize[0], perms, frame->nb_samples, frame->format, av_frame_get_channel_layout(frame)); if (!samplesref) return NULL; if (avfilter_copy_frame_props(samplesref, frame) < 0) { samplesref->buf->data[0] = NULL; avfilter_unref_bufferp(&samplesref); } return samplesref; }
int av_asrc_buffer_add_samples(AVFilterContext *ctx, uint8_t *data[8], int linesize[8], int nb_samples, int sample_rate, int sample_fmt, int64_t channel_layout, int planar, int64_t pts, int av_unused flags) { AVFilterBufferRef *samplesref; samplesref = avfilter_get_audio_buffer_ref_from_arrays( data, linesize, AV_PERM_WRITE, nb_samples, sample_fmt, channel_layout, planar); if (!samplesref) return AVERROR(ENOMEM); samplesref->buf->free = buf_free; samplesref->pts = pts; samplesref->audio->sample_rate = sample_rate; return av_asrc_buffer_add_audio_buffer_ref(ctx, samplesref, 0); }
AVFilterBufferRef *ff_default_get_audio_buffer(AVFilterLink *link, int perms, int nb_samples) { AVFilterBufferRef *samplesref = NULL; uint8_t **data; int planar = av_sample_fmt_is_planar(link->format); int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout); int planes = planar ? nb_channels : 1; int linesize; int full_perms = AV_PERM_READ | AV_PERM_WRITE | AV_PERM_PRESERVE | AV_PERM_REUSE | AV_PERM_REUSE2 | AV_PERM_ALIGN; av_assert1(!(perms & ~(full_perms | AV_PERM_NEG_LINESIZES))); if (!(data = av_mallocz(sizeof(*data) * planes))) goto fail; if (av_samples_alloc(data, &linesize, nb_channels, nb_samples, link->format, 0) < 0) goto fail; samplesref = avfilter_get_audio_buffer_ref_from_arrays(data, linesize, full_perms, nb_samples, link->format, link->channel_layout); if (!samplesref) goto fail; samplesref->audio->sample_rate = link->sample_rate; av_freep(&data); fail: if (data) av_freep(&data[0]); av_freep(&data); return samplesref; }
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); }