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

Reply via email to