<commit_before>/*****************************************************************************
 * audio.c: audio decoder using ffmpeg library
 *****************************************************************************
 * Copyright (C) 1999-2003 the VideoLAN team
 * $Id$
 *
 * Authors: <NAME> <<EMAIL>>
 *          <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <vlc_common.h>
#include <vlc_aout.h>
#include <vlc_codec.h>
#include <vlc_avcodec.h>

/* ffmpeg header */
#ifdef HAVE_LIBAVCODEC_AVCODEC_H
#   include <libavcodec/avcodec.h>
#elif defined(HAVE_FFMPEG_AVCODEC_H)
#   include <ffmpeg/avcodec.h>
#else
#   include <avcodec.h>
#endif

#include "avcodec.h"

/*****************************************************************************
 * decoder_sys_t : decoder descriptor
 *****************************************************************************/
struct decoder_sys_t
{
    FFMPEG_COMMON_MEMBERS

    /* Temporary buffer for libavcodec */
    int     i_output_max;
    uint8_t *p_output;

    /*
     * Output properties
     */
    audio_sample_format_t aout_format;
    audio_date_t          end_date;

    /*
     *
     */
    uint8_t *p_samples;
    int     i_samples;

    /* */
    int     i_reject_count;

    /* */
    bool    b_extract;
    int     pi_extraction[AOUT_CHAN_MAX];
    int     i_previous_channels;
    int64_t i_previous_layout;
};

static void SetupOutputFormat( decoder_t *p_dec, bool b_trust );

/*****************************************************************************
 * InitAudioDec: initialize audio decoder
 *****************************************************************************
 * The ffmpeg codec will be opened, some memory allocated.
 *****************************************************************************/
int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context,
                      AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
{
    decoder_sys_t *p_sys;

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
    {
        return VLC_ENOMEM;
    }

    p_sys->p_context = p_context;
    p_sys->p_codec = p_codec;
    p_sys->i_codec_id = i_codec_id;
    p_sys->psz_namecodec = psz_namecodec;
    p_sys->b_delayed_open = false;

    /* ***** Fill p_context with init values ***** */
    p_sys->p_context->sample_rate = p_dec->fmt_in.audio.i_rate;
    p_sys->p_context->channels = p_dec->fmt_in.audio.i_channels;

    p_sys->p_context->block_align = p_dec->fmt_in.audio.i_blockalign;
    p_sys->p_context->bit_rate = p_dec->fmt_in.i_bitrate;
#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
    p_sys->p_context->bits_per_sample = p_dec->fmt_in.audio.i_bitspersample;
#else
    p_sys->p_context->bits_per_coded_sample = p_dec->fmt_in.audio.i_bitspersample;
#endif

    if( p_dec->fmt_in.i_extra > 0 )
    {
        const uint8_t * const p_src = p_dec->fmt_in.p_extra;
        int i_offset;
        int i_size;

        if( p_dec->fmt_in.i_codec == VLC_CODEC_FLAC )
        {
            i_offset = 8;
            i_size = p_dec->fmt_in.i_extra - 8;
        }
        else if( p_dec->fmt_in.i_codec == VLC_CODEC_ALAC )
        {
            static const uint8_t p_pattern[] = { 0, 0, 0, 36, 'a', 'l', 'a', 'c' };
            /* Find alac atom XXX it is a bit ugly */
            for( i_offset = 0; i_offset < p_dec->fmt_in.i_extra - sizeof(p_pattern); i_offset++ )
            {
                if( !memcmp( &p_src[i_offset], p_pattern, sizeof(p_pattern) ) )
                    break;
            }
            i_size = __MIN( p_dec->fmt_in.i_extra - i_offset, 36 );
            if( i_size < 36 )
                i_size = 0;
        }
        else
        {
            i_offset = 0;
            i_size = p_dec->fmt_in.i_extra;
        }

        if( i_size > 0 )
        {
            p_sys->p_context->extradata =
                malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
            if( p_sys->p_context->extradata )
            {
                uint8_t *p_dst = p_sys->p_context->extradata;

                p_sys->p_context->extradata_size = i_size;

                memcpy( &p_dst[0],            &p_src[i_offset], i_size );
                memset( &p_dst[i_size], 0, FF_INPUT_BUFFER_PADDING_SIZE );
            }
        }
    }
    else
    {
        p_sys->p_context->extradata_size = 0;
        p_sys->p_context->extradata = NULL;
    }

    /* ***** Open the codec ***** */
    int ret;
    vlc_avcodec_lock();
    ret = avcodec_open( p_sys->p_context, p_sys->p_codec );
    vlc_avcodec_unlock();
    if( ret < 0 )
    {
        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
        free( p_sys->p_context->extradata );
        free( p_sys );
        return VLC_EGENERIC;
    }

    msg_Dbg( p_dec, "ffmpeg codec (%s) started", p_sys->psz_namecodec );

    switch( i_codec_id )
    {
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 51, 16, 0 )
    case CODEC_ID_WAVPACK:
        p_sys->i_output_max = 8 * sizeof(int32_t) * 131072;
        break;
#endif
    case CODEC_ID_FLAC:
        p_sys->i_output_max = 8 * sizeof(int32_t) * 65535;
        break;
    default:
        p_sys->i_output_max = 0;
        break;
    }
    if( p_sys->i_output_max < AVCODEC_MAX_AUDIO_FRAME_SIZE )
        p_sys->i_output_max = AVCODEC_MAX_AUDIO_FRAME_SIZE;
    msg_Dbg( p_dec, "Using %d bytes output buffer", p_sys->i_output_max );
    p_sys->p_output = av_malloc( p_sys->i_output_max );<commit_msg>Made sure that our output buffer is large enough with TTA.<commit_after>/*****************************************************************************
 * audio.c: audio decoder using ffmpeg library
 *****************************************************************************
 * Copyright (C) 1999-2003 the VideoLAN team
 * $Id$
 *
 * Authors: <NAME> <<EMAIL>>
 *          <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <vlc_common.h>
#include <vlc_aout.h>
#include <vlc_codec.h>
#include <vlc_avcodec.h>

/* ffmpeg header */
#ifdef HAVE_LIBAVCODEC_AVCODEC_H
#   include <libavcodec/avcodec.h>
#elif defined(HAVE_FFMPEG_AVCODEC_H)
#   include <ffmpeg/avcodec.h>
#else
#   include <avcodec.h>
#endif

#include "avcodec.h"

/*****************************************************************************
 * decoder_sys_t : decoder descriptor
 *****************************************************************************/
struct decoder_sys_t
{
    FFMPEG_COMMON_MEMBERS

    /* Temporary buffer for libavcodec */
    int     i_output_max;
    uint8_t *p_output;

    /*
     * Output properties
     */
    audio_sample_format_t aout_format;
    audio_date_t          end_date;

    /*
     *
     */
    uint8_t *p_samples;
    int     i_samples;

    /* */
    int     i_reject_count;

    /* */
    bool    b_extract;
    int     pi_extraction[AOUT_CHAN_MAX];
    int     i_previous_channels;
    int64_t i_previous_layout;
};

static void SetupOutputFormat( decoder_t *p_dec, bool b_trust );

/*****************************************************************************
 * InitAudioDec: initialize audio decoder
 *****************************************************************************
 * The ffmpeg codec will be opened, some memory allocated.
 *****************************************************************************/
int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context,
                      AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
{
    decoder_sys_t *p_sys;

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
    {
        return VLC_ENOMEM;
    }

    p_sys->p_context = p_context;
    p_sys->p_codec = p_codec;
    p_sys->i_codec_id = i_codec_id;
    p_sys->psz_namecodec = psz_namecodec;
    p_sys->b_delayed_open = false;

    /* ***** Fill p_context with init values ***** */
    p_sys->p_context->sample_rate = p_dec->fmt_in.audio.i_rate;
    p_sys->p_context->channels = p_dec->fmt_in.audio.i_channels;

    p_sys->p_context->block_align = p_dec->fmt_in.audio.i_blockalign;
    p_sys->p_context->bit_rate = p_dec->fmt_in.i_bitrate;
#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
    p_sys->p_context->bits_per_sample = p_dec->fmt_in.audio.i_bitspersample;
#else
    p_sys->p_context->bits_per_coded_sample = p_dec->fmt_in.audio.i_bitspersample;
#endif

    if( p_dec->fmt_in.i_extra > 0 )
    {
        const uint8_t * const p_src = p_dec->fmt_in.p_extra;
        int i_offset;
        int i_size;

        if( p_dec->fmt_in.i_codec == VLC_CODEC_FLAC )
        {
            i_offset = 8;
            i_size = p_dec->fmt_in.i_extra - 8;
        }
        else if( p_dec->fmt_in.i_codec == VLC_CODEC_ALAC )
        {
            static const uint8_t p_pattern[] = { 0, 0, 0, 36, 'a', 'l', 'a', 'c' };
            /* Find alac atom XXX it is a bit ugly */
            for( i_offset = 0; i_offset < p_dec->fmt_in.i_extra - sizeof(p_pattern); i_offset++ )
            {
                if( !memcmp( &p_src[i_offset], p_pattern, sizeof(p_pattern) ) )
                    break;
            }
            i_size = __MIN( p_dec->fmt_in.i_extra - i_offset, 36 );
            if( i_size < 36 )
                i_size = 0;
        }
        else
        {
            i_offset = 0;
            i_size = p_dec->fmt_in.i_extra;
        }

        if( i_size > 0 )
        {
            p_sys->p_context->extradata =
                malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
            if( p_sys->p_context->extradata )
            {
                uint8_t *p_dst = p_sys->p_context->extradata;

                p_sys->p_context->extradata_size = i_size;

                memcpy( &p_dst[0],            &p_src[i_offset], i_size );
                memset( &p_dst[i_size], 0, FF_INPUT_BUFFER_PADDING_SIZE );
            }
        }
    }
    else
    {
        p_sys->p_context->extradata_size = 0;
        p_sys->p_context->extradata = NULL;
    }

    /* ***** Open the codec ***** */
    int ret;
    vlc_avcodec_lock();
    ret = avcodec_open( p_sys->p_context, p_sys->p_codec );
    vlc_avcodec_unlock();
    if( ret < 0 )
    {
        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
        free( p_sys->p_context->extradata );
        free( p_sys );
        return VLC_EGENERIC;
    }

    msg_Dbg( p_dec, "ffmpeg codec (%s) started", p_sys->psz_namecodec );

    switch( i_codec_id )
    {
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 51, 16, 0 )
    case CODEC_ID_WAVPACK:
        p_sys->i_output_max = 8 * sizeof(int32_t) * 131072;
        break;
#endif
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 51, 4, 0 )
    case CODEC_ID_TTA:
        p_sys->i_output_max = p_sys->p_context->channels * sizeof(int32_t) * p_sys->p_context->sample_rate * 2;
        break;
#endif
    case CODEC_ID_FLAC:
        p_sys->i_output_max = 8 * sizeof(int32_t) * 65535;
        break;
    default:
        p_sys->i_output_max = 0;
        break;
    }
    if( p_sys->i_output_max < AVCODEC_MAX_AUDIO_FRAME_SIZE )
        p_sys->i_output_max = AVCODEC_MAX_AUDIO_FRAME_SIZE;
    msg_Dbg( p_dec, "Using %d bytes output buffer", p_sys->i_output_max );
    p_sys->p_output = av_malloc( p_sys->i_output_max );
{'fraction_non_alphanumeric': 0.21516408902301018, 'fraction_numerical': 0.012146359864202188, 'mean_word_length': 2.860221316249272, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 157, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6513668', 'n_tokens_mistral': 4552, 'n_tokens_neox': 4265, 'n_words': 939}