enum AVSampleFormat sample_fmt, int nb_samples,
uint64_t channel_layout)
{
- AVFilterBuffer *samples = av_mallocz(sizeof(AVFilterBuffer));
- AVFilterBufferRef *ref = NULL;
- int i, sample_size, chans_nb, bufsize, per_channel_size, step_size = 0;
- int planar = av_sample_fmt_is_planar(sample_fmt);
- char *buf;
-
- if (!samples || !(ref = av_mallocz(sizeof(AVFilterBufferRef))))
+ AVFilterBufferRef *samplesref = NULL;
+ uint8_t **data;
+ int planar = av_sample_fmt_is_planar(sample_fmt);
+ int nb_channels = av_get_channel_layout_nb_channels(channel_layout);
+ int planes = planar ? nb_channels : 1;
+ int linesize;
+
+ if (!(data = av_mallocz(sizeof(*data) * planes)))
goto fail;
- ref->buf = samples;
- ref->format = sample_fmt;
-
- ref->audio = av_mallocz(sizeof(AVFilterBufferRefAudioProps));
- if (!ref->audio)
+ if (av_samples_alloc(data, &linesize, nb_channels, nb_samples, sample_fmt, 0) < 0)
goto fail;
- ref->audio->channel_layout = channel_layout;
- ref->audio->nb_samples = nb_samples;
- ref->audio->planar = planar;
-
- /* make sure the buffer gets read permission or it's useless for output */
- ref->perms = perms | AV_PERM_READ;
-
- samples->refcount = 1;
- samples->free = ff_avfilter_default_free_buffer;
-
- sample_size = av_get_bytes_per_sample(sample_fmt);
- chans_nb = av_get_channel_layout_nb_channels(channel_layout);
-
- per_channel_size = nb_samples * sample_size;
-
- /* Set the number of bytes to traverse to reach next sample of a particular channel:
- * For planar, this is simply the sample size.
- * For packed, this is the number of samples * sample_size.
- */
- for (i = 0; i < chans_nb; i++)
- samples->linesize[i] = planar > 0 ? per_channel_size : sample_size;
- memset(&samples->linesize[chans_nb], 0, (8-chans_nb) * sizeof(samples->linesize[0]));
-
- /* Calculate total buffer size, round to multiple of 16 to be SIMD friendly */
- bufsize = (nb_samples * chans_nb * sample_size + 15)&~15;
- buf = av_malloc(bufsize);
- if (!buf)
+ samplesref = avfilter_get_audio_buffer_ref_from_arrays(data, linesize, perms,
+ nb_samples, sample_fmt,
+ channel_layout);
+ if (!samplesref)
goto fail;
- /* For planar, set the start point of each channel's data within the buffer
- * For packed, set the start point of the entire buffer only
- */
- samples->data[0] = buf;
- if (buf && planar) {
- for (i = 1; i < chans_nb; i++) {
- step_size += per_channel_size;
- samples->data[i] = buf + step_size;
- }
- } else {
- for (i = 1; i < chans_nb; i++)
- samples->data[i] = buf;
- }
-
- memset(&samples->data[chans_nb], 0, (8-chans_nb) * sizeof(samples->data[0]));
-
- memcpy(ref->data, samples->data, sizeof(ref->data));
- memcpy(ref->linesize, samples->linesize, sizeof(ref->linesize));
-
- return ref;
+ av_freep(&data);
fail:
- if (ref)
- av_free(ref->audio);
- av_free(ref);
- av_free(samples);
- return NULL;
+ if (data)
+ av_freep(&data[0]);
+ av_freep(&data);
+ return samplesref;
}
void avfilter_default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)