On Mon, 9 Apr 2012 17:27:52 -0400, Justin Ruggles <[email protected]>
wrote:
> This is a new library for audio sample format, channel layout, and sample rate
> conversion.
> libavresample/audio_data.c | 342 ++++++++++++++++++++++++
> libavresample/audio_data.h | 167 ++++++++++++
> diff --git a/libavresample/audio_data.c b/libavresample/audio_data.c
> new file mode 100644
> index 0000000..9b53fe0
> --- /dev/null
> +++ b/libavresample/audio_data.c
> @@ -0,0 +1,342 @@
> +/*
> + * Copyright (c) 2012 Justin Ruggles <[email protected]>
> + *
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> USA
> + */
> +
> +#include <stdint.h>
> +
> +#include "libavutil/mem.h"
> +#include "audio_data.h"
> +
> +/*
> + * Calculate alignment for data pointers and number of samples
> + */
> +static void calc_alignment(AudioData *a)
> +{
> + int p;
> + int min_align = 1024;
> +
> + for (p = 0; p < a->planes; p++) {
> + int cur_align = 1024;
> + while ((intptr_t)a->data[p] % cur_align)
> + cur_align >>= 1;
> + if (cur_align < min_align)
> + min_align = cur_align;
> + }
> + a->ptr_align = min_align;
> + a->samples_align = FFMAX(1, a->plane_size / a->stride);
> +}
> +
> +int ff_audio_data_set_channels(AudioData *a, int channels)
> +{
> + if (channels < 1 || channels > AVRESAMPLE_MAX_CHANNELS ||
> + channels > a->allocated_channels)
> + return AVERROR(EINVAL);
> +
> + a->channels = channels;
> + a->planes = a->is_planar ? channels : 1;
> +
> + calc_alignment(a);
> +
> + return 0;
> +}
> +
> +int ff_audio_data_init(AudioData *a, void **src, int plane_size, int
> channels,
> + int nb_samples, enum AVSampleFormat sample_fmt,
> + int read_only, const char *name)
> +{
> + int p;
> +
> + if (channels < 1 || channels > AVRESAMPLE_MAX_CHANNELS) {
> + av_log(NULL, AV_LOG_ERROR, "bad channel count: %d\n", channels);
> + return AVERROR(EINVAL);
> + }
> +
> + memset(a, 0, sizeof(*a));
> +
> + a->sample_size = av_get_bytes_per_sample(sample_fmt);
> + if (!a->sample_size) {
> + av_log(NULL, AV_LOG_ERROR, "bad sample format\n");
> + return AVERROR(EINVAL);
> + }
> + a->is_planar = av_sample_fmt_is_planar(sample_fmt);
> + a->planes = a->is_planar ? channels : 1;
> + a->stride = a->sample_size * (a->is_planar ? 1 : channels);
> +
> + for (p = 0; p < (a->is_planar ? channels : 1); p++) {
> + if (!src[p]) {
> + av_log(NULL, AV_LOG_ERROR, "invalid plane=%d channels=%d\n", p,
> channels);
> + return AVERROR(EINVAL);
> + }
> + a->data[p] = src[p];
> + }
> + a->buffer = NULL;
> + a->buffer_size = 0;
> + a->allocated_samples = nb_samples * !read_only;
> + a->nb_samples = nb_samples;
> + a->sample_fmt = sample_fmt;
> + a->channels = channels;
> + a->allocated_channels = channels;
> + a->read_only = read_only;
> + a->allow_realloc = 0;
> + a->plane_size = plane_size;
> + a->name = name ? name : "{no name}";
> +
> + calc_alignment(a);
> +
> + return 0;
> +}
> +
> +AudioData *ff_audio_data_alloc(int channels, int nb_samples,
> + enum AVSampleFormat sample_fmt, const char
> *name)
> +{
> + AudioData *a;
> + int ret;
> +
> + if (channels < 1 || channels > AVRESAMPLE_MAX_CHANNELS)
> + return NULL;
> +
> + a = av_mallocz(sizeof(*a));
> + if (!a)
> + return NULL;
> +
> + a->sample_size = av_get_bytes_per_sample(sample_fmt);
> + if (!a->sample_size)
> + return NULL;
leaks a
> + a->is_planar = av_sample_fmt_is_planar(sample_fmt);
> + a->planes = a->is_planar ? channels : 1;
> + a->stride = a->sample_size * (a->is_planar ? 1 : channels);
> +
> + a->buffer = NULL;
> + a->buffer_size = 0;
> + a->allocated_samples = 0;
> + a->nb_samples = 0;
You just malloczed those.
[...]
> +
> +int ff_audio_data_add_to_fifo(AVAudioFifo *af, AudioData *a, int offset,
> + int nb_samples)
> +{
> + uint8_t *offset_data[AVRESAMPLE_MAX_CHANNELS];
> + int offset_size, planes, p;
> +
> + if (offset >= a->nb_samples)
> + return 0;
> + offset_size = offset * a->sample_size * (a->is_planar ? 1 : a->channels);
\______________________ ________________________/
v
a->stride?
Also it seems to me Audiodata needs an AVClass.
> + planes = a->is_planar ? a->channels : 1;
> + for (p = 0; p < planes; p++)
> + offset_data[p] = a->data[p] + offset_size;
> +
> + return av_audio_fifo_write(af, (void **)offset_data, nb_samples);
> +}
> +
> +int ff_audio_data_read_from_fifo(AVAudioFifo *af, AudioData *a, int
> nb_samples)
> +{
> + int ret;
> +
> + if (a->read_only)
> + return AVERROR(EINVAL);
> +
> + ret = ff_audio_data_realloc(a, nb_samples);
> + if (ret < 0)
> + return ret;
> +
> + ret = av_audio_fifo_read(af, (void **)a->data, nb_samples);
> + if (ret >= 0)
> + a->nb_samples = ret;
> + return ret;
> +}
> diff --git a/libavresample/audio_data.h b/libavresample/audio_data.h
> new file mode 100644
> index 0000000..29d1448
> --- /dev/null
> +++ b/libavresample/audio_data.h
> @@ -0,0 +1,167 @@
> +/*
> + * Copyright (c) 2012 Justin Ruggles <[email protected]>
> + *
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> USA
> + */
> +
> +#ifndef AVRESAMPLE_AUDIO_DATA_H
> +#define AVRESAMPLE_AUDIO_DATA_H
> +
> +#include <stdint.h>
> +
> +#include "libavutil/audio_fifo.h"
> +#include "libavutil/samplefmt.h"
> +#include "avresample.h"
> +
> +/**
> + * Audio buffer used for intermediate storage between conversion phases.
> + */
> +typedef struct AudioData {
> + uint8_t *data[AVRESAMPLE_MAX_CHANNELS]; /**< data plane pointers
> */
> + uint8_t *buffer; /**< data buffer
> */
> + unsigned int buffer_size; /**< allocated buffer size
> */
> + int allocated_samples; /**< number of samples the buffer
> can hold */
> + int nb_samples; /**< current number of samples
> */
> + enum AVSampleFormat sample_fmt; /**< sample format
> */
> + int channels; /**< channel count
> */
> + int allocated_channels; /**< allocated channel count
> */
> + int is_planar; /**< sample format is planar
> */
> + int planes; /**< number of data planes
> */
> + int sample_size; /**< bytes per sample
> */
> + int stride; /**< sample byte offset within a
> plane */
> + int plane_size; /**< size of each plane, in bytes
> */
> + int read_only; /**< data is read-only
> */
> + int allow_realloc; /**< realloc is allowed
> */
> + int ptr_align; /**< minimum data pointer alignment
> */
> + int samples_align; /**< allocated samples alignment
> */
> + const char *name; /**< name for debug logging
> */
> +} AudioData;
> +
> +int ff_audio_data_set_channels(AudioData *a, int channels);
> +
> +/**
> + * Initialize AudioData using a given source.
> + *
> + * This does not allocate an internal buffer. It only sets the data pointers
> + * and audio parameters.
> + *
> + * @param a AudioData struct
> + * @param src source data pointers
> + * @param channels channel count
> + * @param nb_samples number of samples in the source data
> + * @param sample_fmt sample format
> + * @param read_only indicates if buffer is read only or read/write
> + * @param name name for debug logging (can be NULL)
> + * @return 0 on success, negative AVERROR value on error
> + */
> +int ff_audio_data_init(AudioData *a, void **src, int plane_size, int
> channels,
> + int nb_samples, enum AVSampleFormat sample_fmt,
> + int read_only, const char *name);
> +
> +/**
> + * Allocate AudioData.
> + *
> + * This allocates an internal buffer and sets audio parameters.
> + *
> + * @param channels channel count
> + * @param nb_samples number of samples to allocate space for
> + * @param sample_fmt sample format
> + * @param name name for debug logging (can be NULL)
> + * @return newly allocated AudioData struct, or NULL on error
> + */
> +AudioData *ff_audio_data_alloc(int channels, int nb_samples,
> + enum AVSampleFormat sample_fmt,
> + const char *name);
> +
> +/**
> + * Reallocate AudioData.
> + *
> + * The AudioData must have been previously allocated with
> ff_audio_data_alloc()
> + *
> + * @param a AudioData struct
> + * @param nb_samples number of samples to allocate space for
> + * @return 0 on success, negative AVERROR value on error
> + */
> +int ff_audio_data_realloc(AudioData *a, int nb_samples);
> +
> +/**
> + * Free AudioData.
> + *
> + * The AudioData must have been previously allocated with
> ff_audio_data_alloc()
> + *
> + * @param a AudioData struct
> + */
> +void ff_audio_data_free(AudioData **a);
> +
> +/**
> + * Copy data from one AudioData to another.
> + *
> + * @param out output AudioData
> + * @param in input AudioData
> + * @return 0 on success, negative AVERROR value on error
> + */
> +int ff_audio_data_copy(AudioData *out, AudioData *in);
> +
> +/**
> + * Append data from one AudioData to the end of another.
> + *
> + * @param dst destination AudioData
> + * @param prepend add to the beginning of dst instead of the end
Doesn't exist.
--
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel