2001-07-22 14:18:56 +00:00
/*
2008-08-03 16:42:32 +00:00
* The simplest AC - 3 encoder
2009-01-19 15:46:40 +00:00
* Copyright ( c ) 2000 Fabrice Bellard
2010-12-16 21:09:02 +00:00
* Copyright ( c ) 2006 - 2010 Justin Ruggles < justin . ruggles @ gmail . com >
* Copyright ( c ) 2006 - 2010 Prakash Punnoor < prakash @ punnoor . de >
2001-07-22 14:18:56 +00:00
*
2006-10-07 15:30:46 +00:00
* This file is part of FFmpeg .
*
* FFmpeg is free software ; you can redistribute it and / or
2002-05-25 22:45:33 +00:00
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
2006-10-07 15:30:46 +00:00
* version 2.1 of the License , or ( at your option ) any later version .
2001-07-22 14:18:56 +00:00
*
2006-10-07 15:30:46 +00:00
* FFmpeg is distributed in the hope that it will be useful ,
2001-07-22 14:18:56 +00:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
2002-05-25 22:45:33 +00:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
2001-07-22 14:18:56 +00:00
*
2002-05-25 22:45:33 +00:00
* You should have received a copy of the GNU Lesser General Public
2006-10-07 15:30:46 +00:00
* License along with FFmpeg ; if not , write to the Free Software
2006-01-12 22:43:26 +00:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2001-07-22 14:18:56 +00:00
*/
2003-03-06 11:32:04 +00:00
/**
2010-04-20 14:45:34 +00:00
* @ file
2008-08-03 16:42:32 +00:00
* The simplest AC - 3 encoder .
2003-03-06 11:32:04 +00:00
*/
2010-12-14 14:51:09 +00:00
2011-03-21 18:07:59 +00:00
# include <stdint.h>
2013-02-01 09:31:59 +00:00
# include "libavutil/attributes.h"
2011-03-04 17:11:03 +00:00
# include "libavutil/avassert.h"
2011-05-03 18:19:31 +00:00
# include "libavutil/avstring.h"
2012-11-10 15:00:00 +00:00
# include "libavutil/channel_layout.h"
2008-05-09 11:56:36 +00:00
# include "libavutil/crc.h"
2013-02-07 23:31:13 +00:00
# include "libavutil/internal.h"
2022-05-23 03:23:35 +00:00
# include "libavutil/mem_internal.h"
2011-03-25 21:12:26 +00:00
# include "libavutil/opt.h"
2022-05-23 03:23:35 +00:00
# include "libavutil/thread.h"
2001-07-22 14:18:56 +00:00
# include "avcodec.h"
2024-04-25 09:18:18 +00:00
# include "codec_internal.h"
# include "config_components.h"
# include "encode.h"
2015-04-20 02:11:23 +00:00
# include "internal.h"
2014-02-08 01:59:58 +00:00
# include "me_cmp.h"
2009-04-12 08:35:26 +00:00
# include "put_bits.h"
2014-01-16 16:30:19 +00:00
# include "audiodsp.h"
2011-02-10 17:20:36 +00:00
# include "ac3dsp.h"
2002-10-28 00:39:05 +00:00
# include "ac3.h"
2024-04-25 09:18:18 +00:00
# include "ac3defs.h"
# include "ac3tab.h"
2011-03-21 18:07:59 +00:00
# include "fft.h"
2011-06-07 16:47:09 +00:00
# include "ac3enc.h"
# include "eac3enc.h"
2001-07-22 14:18:56 +00:00
2011-03-13 16:22:07 +00:00
typedef struct AC3Mant {
2011-06-21 17:39:02 +00:00
int16_t * qmant1_ptr , * qmant2_ptr , * qmant4_ptr ; ///< mantissa pointers for bap=1,2,4
2011-03-13 16:22:07 +00:00
int mant1_cnt , mant2_cnt , mant4_cnt ; ///< mantissa counts for bap=1,2,4
} AC3Mant ;
2010-12-14 14:51:26 +00:00
2011-03-25 21:12:26 +00:00
# define CMIXLEV_NUM_OPTIONS 3
static const float cmixlev_options [ CMIXLEV_NUM_OPTIONS ] = {
LEVEL_MINUS_3DB , LEVEL_MINUS_4POINT5DB , LEVEL_MINUS_6DB
} ;
# define SURMIXLEV_NUM_OPTIONS 3
static const float surmixlev_options [ SURMIXLEV_NUM_OPTIONS ] = {
LEVEL_MINUS_3DB , LEVEL_MINUS_6DB , LEVEL_ZERO
} ;
# define EXTMIXLEV_NUM_OPTIONS 8
static const float extmixlev_options [ EXTMIXLEV_NUM_OPTIONS ] = {
2020-04-30 16:17:36 +00:00
LEVEL_PLUS_3DB , LEVEL_PLUS_1POINT5DB , LEVEL_ONE , LEVEL_MINUS_1POINT5DB ,
2011-03-25 21:12:26 +00:00
LEVEL_MINUS_3DB , LEVEL_MINUS_4POINT5DB , LEVEL_MINUS_6DB , LEVEL_ZERO
} ;
2022-05-23 03:23:35 +00:00
/* The first two options apply only to the AC-3 encoders;
* the rest is also valid for EAC - 3. When modifying it ,
* it might be necessary to adapt said offset in eac3enc . c . */
# define OFFSET(param) offsetof(AC3EncodeContext, options.param)
# define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
const AVOption ff_ac3_enc_options [ ] = {
/* AC-3 downmix levels */
{ " center_mixlev " , " Center Mix Level " , OFFSET ( center_mix_level ) , AV_OPT_TYPE_FLOAT , { . dbl = LEVEL_MINUS_4POINT5DB } , 0.0 , 1.0 , AC3ENC_PARAM } ,
{ " surround_mixlev " , " Surround Mix Level " , OFFSET ( surround_mix_level ) , AV_OPT_TYPE_FLOAT , { . dbl = LEVEL_MINUS_6DB } , 0.0 , 1.0 , AC3ENC_PARAM } ,
/* audio production information */
{ " mixing_level " , " Mixing Level " , OFFSET ( mixing_level ) , AV_OPT_TYPE_INT , { . i64 = AC3ENC_OPT_NONE } , AC3ENC_OPT_NONE , 111 , AC3ENC_PARAM } ,
{ " room_type " , " Room Type " , OFFSET ( room_type ) , AV_OPT_TYPE_INT , { . i64 = AC3ENC_OPT_NONE } , AC3ENC_OPT_NONE , AC3ENC_OPT_SMALL_ROOM , AC3ENC_PARAM , " room_type " } ,
{ " notindicated " , " Not Indicated (default) " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_NOT_INDICATED } , INT_MIN , INT_MAX , AC3ENC_PARAM , " room_type " } ,
{ " large " , " Large Room " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_LARGE_ROOM } , INT_MIN , INT_MAX , AC3ENC_PARAM , " room_type " } ,
{ " small " , " Small Room " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_SMALL_ROOM } , INT_MIN , INT_MAX , AC3ENC_PARAM , " room_type " } ,
/* Metadata Options */
{ " per_frame_metadata " , " Allow Changing Metadata Per-Frame " , OFFSET ( allow_per_frame_metadata ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , AC3ENC_PARAM } ,
{ " copyright " , " Copyright Bit " , OFFSET ( copyright ) , AV_OPT_TYPE_INT , { . i64 = AC3ENC_OPT_NONE } , AC3ENC_OPT_NONE , 1 , AC3ENC_PARAM } ,
{ " dialnorm " , " Dialogue Level (dB) " , OFFSET ( dialogue_level ) , AV_OPT_TYPE_INT , { . i64 = - 31 } , - 31 , - 1 , AC3ENC_PARAM } ,
{ " dsur_mode " , " Dolby Surround Mode " , OFFSET ( dolby_surround_mode ) , AV_OPT_TYPE_INT , { . i64 = AC3ENC_OPT_NONE } , AC3ENC_OPT_NONE , AC3ENC_OPT_MODE_ON , AC3ENC_PARAM , " dsur_mode " } ,
{ " notindicated " , " Not Indicated (default) " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_NOT_INDICATED } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dsur_mode " } ,
{ " on " , " Dolby Surround Encoded " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_MODE_ON } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dsur_mode " } ,
{ " off " , " Not Dolby Surround Encoded " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_MODE_OFF } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dsur_mode " } ,
{ " original " , " Original Bit Stream " , OFFSET ( original ) , AV_OPT_TYPE_INT , { . i64 = AC3ENC_OPT_NONE } , AC3ENC_OPT_NONE , 1 , AC3ENC_PARAM } ,
/* extended bitstream information */
{ " dmix_mode " , " Preferred Stereo Downmix Mode " , OFFSET ( preferred_stereo_downmix ) , AV_OPT_TYPE_INT , { . i64 = AC3ENC_OPT_NONE } , AC3ENC_OPT_NONE , AC3ENC_OPT_DOWNMIX_DPLII , AC3ENC_PARAM , " dmix_mode " } ,
{ " notindicated " , " Not Indicated (default) " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_NOT_INDICATED } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dmix_mode " } ,
{ " ltrt " , " Lt/Rt Downmix Preferred " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_DOWNMIX_LTRT } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dmix_mode " } ,
{ " loro " , " Lo/Ro Downmix Preferred " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_DOWNMIX_LORO } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dmix_mode " } ,
{ " dplii " , " Dolby Pro Logic II Downmix Preferred " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_DOWNMIX_DPLII } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dmix_mode " } ,
{ " ltrt_cmixlev " , " Lt/Rt Center Mix Level " , OFFSET ( ltrt_center_mix_level ) , AV_OPT_TYPE_FLOAT , { . dbl = - 1.0 } , - 1.0 , 2.0 , AC3ENC_PARAM } ,
{ " ltrt_surmixlev " , " Lt/Rt Surround Mix Level " , OFFSET ( ltrt_surround_mix_level ) , AV_OPT_TYPE_FLOAT , { . dbl = - 1.0 } , - 1.0 , 2.0 , AC3ENC_PARAM } ,
{ " loro_cmixlev " , " Lo/Ro Center Mix Level " , OFFSET ( loro_center_mix_level ) , AV_OPT_TYPE_FLOAT , { . dbl = - 1.0 } , - 1.0 , 2.0 , AC3ENC_PARAM } ,
{ " loro_surmixlev " , " Lo/Ro Surround Mix Level " , OFFSET ( loro_surround_mix_level ) , AV_OPT_TYPE_FLOAT , { . dbl = - 1.0 } , - 1.0 , 2.0 , AC3ENC_PARAM } ,
{ " dsurex_mode " , " Dolby Surround EX Mode " , OFFSET ( dolby_surround_ex_mode ) , AV_OPT_TYPE_INT , { . i64 = AC3ENC_OPT_NONE } , AC3ENC_OPT_NONE , AC3ENC_OPT_DSUREX_DPLIIZ , AC3ENC_PARAM , " dsurex_mode " } ,
{ " notindicated " , " Not Indicated (default) " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_NOT_INDICATED } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dsurex_mode " } ,
{ " on " , " Dolby Surround EX Encoded " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_MODE_ON } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dsurex_mode " } ,
{ " off " , " Not Dolby Surround EX Encoded " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_MODE_OFF } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dsurex_mode " } ,
{ " dpliiz " , " Dolby Pro Logic IIz-encoded " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_DSUREX_DPLIIZ } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dsurex_mode " } ,
{ " dheadphone_mode " , " Dolby Headphone Mode " , OFFSET ( dolby_headphone_mode ) , AV_OPT_TYPE_INT , { . i64 = AC3ENC_OPT_NONE } , AC3ENC_OPT_NONE , AC3ENC_OPT_MODE_ON , AC3ENC_PARAM , " dheadphone_mode " } ,
{ " notindicated " , " Not Indicated (default) " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_NOT_INDICATED } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dheadphone_mode " } ,
{ " on " , " Dolby Headphone Encoded " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_MODE_ON } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dheadphone_mode " } ,
{ " off " , " Not Dolby Headphone Encoded " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_MODE_OFF } , INT_MIN , INT_MAX , AC3ENC_PARAM , " dheadphone_mode " } ,
{ " ad_conv_type " , " A/D Converter Type " , OFFSET ( ad_converter_type ) , AV_OPT_TYPE_INT , { . i64 = AC3ENC_OPT_NONE } , AC3ENC_OPT_NONE , AC3ENC_OPT_ADCONV_HDCD , AC3ENC_PARAM , " ad_conv_type " } ,
{ " standard " , " Standard (default) " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_ADCONV_STANDARD } , INT_MIN , INT_MAX , AC3ENC_PARAM , " ad_conv_type " } ,
{ " hdcd " , " HDCD " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_ADCONV_HDCD } , INT_MIN , INT_MAX , AC3ENC_PARAM , " ad_conv_type " } ,
/* Other Encoding Options */
{ " stereo_rematrixing " , " Stereo Rematrixing " , OFFSET ( stereo_rematrixing ) , AV_OPT_TYPE_BOOL , { . i64 = 1 } , 0 , 1 , AC3ENC_PARAM } ,
{ " channel_coupling " , " Channel Coupling " , OFFSET ( channel_coupling ) , AV_OPT_TYPE_INT , { . i64 = AC3ENC_OPT_AUTO } , AC3ENC_OPT_AUTO , AC3ENC_OPT_ON , AC3ENC_PARAM , " channel_coupling " } ,
{ " auto " , " Selected by the Encoder " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_AUTO } , INT_MIN , INT_MAX , AC3ENC_PARAM , " channel_coupling " } ,
{ " cpl_start_band " , " Coupling Start Band " , OFFSET ( cpl_start ) , AV_OPT_TYPE_INT , { . i64 = AC3ENC_OPT_AUTO } , AC3ENC_OPT_AUTO , 15 , AC3ENC_PARAM , " cpl_start_band " } ,
{ " auto " , " Selected by the Encoder " , 0 , AV_OPT_TYPE_CONST , { . i64 = AC3ENC_OPT_AUTO } , INT_MIN , INT_MAX , AC3ENC_PARAM , " cpl_start_band " } ,
{ NULL }
} ;
2024-04-25 09:18:18 +00:00
const AVClass ff_ac3enc_class = {
. class_name = " AC-3 Encoder " ,
. item_name = av_default_item_name ,
. option = ff_ac3_enc_options ,
. version = LIBAVUTIL_VERSION_INT ,
} ;
const FFCodecDefault ff_ac3_enc_defaults [ ] = {
2022-05-23 03:23:35 +00:00
{ " b " , " 0 " } ,
{ NULL }
} ;
2011-03-25 21:12:26 +00:00
2010-12-16 21:09:22 +00:00
/**
* LUT for number of exponent groups .
2011-05-23 15:45:51 +00:00
* exponent_group_tab [ coupling ] [ exponent strategy - 1 ] [ number of coefficients ]
2010-12-16 21:09:22 +00:00
*/
2011-05-23 15:45:51 +00:00
static uint8_t exponent_group_tab [ 2 ] [ 3 ] [ 256 ] ;
2010-12-16 21:09:22 +00:00
2010-12-14 14:51:26 +00:00
2010-12-30 22:13:41 +00:00
/**
* List of supported channel layouts .
*/
2024-04-25 09:18:18 +00:00
# if FF_API_OLD_CHANNEL_LAYOUT
2011-11-25 12:51:57 +00:00
const uint64_t ff_ac3_channel_layouts [ 19 ] = {
2010-12-30 22:13:41 +00:00
AV_CH_LAYOUT_MONO ,
AV_CH_LAYOUT_STEREO ,
AV_CH_LAYOUT_2_1 ,
AV_CH_LAYOUT_SURROUND ,
AV_CH_LAYOUT_2_2 ,
AV_CH_LAYOUT_QUAD ,
AV_CH_LAYOUT_4POINT0 ,
AV_CH_LAYOUT_5POINT0 ,
AV_CH_LAYOUT_5POINT0_BACK ,
( AV_CH_LAYOUT_MONO | AV_CH_LOW_FREQUENCY ) ,
( AV_CH_LAYOUT_STEREO | AV_CH_LOW_FREQUENCY ) ,
( AV_CH_LAYOUT_2_1 | AV_CH_LOW_FREQUENCY ) ,
( AV_CH_LAYOUT_SURROUND | AV_CH_LOW_FREQUENCY ) ,
( AV_CH_LAYOUT_2_2 | AV_CH_LOW_FREQUENCY ) ,
( AV_CH_LAYOUT_QUAD | AV_CH_LOW_FREQUENCY ) ,
( AV_CH_LAYOUT_4POINT0 | AV_CH_LOW_FREQUENCY ) ,
AV_CH_LAYOUT_5POINT1 ,
AV_CH_LAYOUT_5POINT1_BACK ,
0
} ;
2024-04-25 09:18:18 +00:00
# endif
const AVChannelLayout ff_ac3_ch_layouts [ 19 ] = {
AV_CHANNEL_LAYOUT_MONO ,
AV_CHANNEL_LAYOUT_STEREO ,
AV_CHANNEL_LAYOUT_2_1 ,
AV_CHANNEL_LAYOUT_SURROUND ,
AV_CHANNEL_LAYOUT_2_2 ,
AV_CHANNEL_LAYOUT_QUAD ,
AV_CHANNEL_LAYOUT_4POINT0 ,
AV_CHANNEL_LAYOUT_5POINT0 ,
AV_CHANNEL_LAYOUT_5POINT0_BACK ,
{
. nb_channels = 2 ,
. order = AV_CHANNEL_ORDER_NATIVE ,
. u . mask = AV_CH_LAYOUT_MONO | AV_CH_LOW_FREQUENCY ,
} ,
{
. nb_channels = 3 ,
. order = AV_CHANNEL_ORDER_NATIVE ,
. u . mask = AV_CH_LAYOUT_STEREO | AV_CH_LOW_FREQUENCY ,
} ,
{
. nb_channels = 4 ,
. order = AV_CHANNEL_ORDER_NATIVE ,
. u . mask = AV_CH_LAYOUT_2_1 | AV_CH_LOW_FREQUENCY ,
} ,
{
. nb_channels = 4 ,
. order = AV_CHANNEL_ORDER_NATIVE ,
. u . mask = AV_CH_LAYOUT_SURROUND | AV_CH_LOW_FREQUENCY ,
} ,
{
. nb_channels = 5 ,
. order = AV_CHANNEL_ORDER_NATIVE ,
. u . mask = AV_CH_LAYOUT_4POINT0 | AV_CH_LOW_FREQUENCY ,
} ,
AV_CHANNEL_LAYOUT_5POINT1 ,
AV_CHANNEL_LAYOUT_5POINT1_BACK ,
{ 0 } ,
} ;
2010-12-30 22:13:41 +00:00
2022-05-23 03:23:35 +00:00
/**
* Table to remap channels from SMPTE order to AC - 3 order .
* [ channel_mode ] [ lfe ] [ ch ]
*/
static const uint8_t ac3_enc_channel_map [ 8 ] [ 2 ] [ 6 ] = {
COMMON_CHANNEL_MAP
{ { 0 , 1 , 2 , 3 , } , { 0 , 1 , 3 , 4 , 2 , } } ,
{ { 0 , 2 , 1 , 3 , 4 , } , { 0 , 2 , 1 , 4 , 5 , 3 } } ,
} ;
2010-12-30 22:13:41 +00:00
2011-03-28 13:18:37 +00:00
/**
* LUT to select the bandwidth code based on the bit rate , sample rate , and
* number of full - bandwidth channels .
* bandwidth_tab [ fbw_channels - 1 ] [ sample rate code ] [ bit rate code ]
*/
static const uint8_t ac3_bandwidth_tab [ 5 ] [ 3 ] [ 19 ] = {
// 32 40 48 56 64 80 96 112 128 160 192 224 256 320 384 448 512 576 640
{ { 0 , 0 , 0 , 12 , 16 , 32 , 48 , 48 , 48 , 48 , 48 , 48 , 48 , 48 , 48 , 48 , 48 , 48 , 48 } ,
{ 0 , 0 , 0 , 16 , 20 , 36 , 56 , 56 , 56 , 56 , 56 , 56 , 56 , 56 , 56 , 56 , 56 , 56 , 56 } ,
{ 0 , 0 , 0 , 32 , 40 , 60 , 60 , 60 , 60 , 60 , 60 , 60 , 60 , 60 , 60 , 60 , 60 , 60 , 60 } } ,
{ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 20 , 24 , 32 , 48 , 48 , 48 , 48 , 48 , 48 , 48 , 48 , 48 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 4 , 24 , 28 , 36 , 56 , 56 , 56 , 56 , 56 , 56 , 56 , 56 , 56 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 20 , 44 , 52 , 60 , 60 , 60 , 60 , 60 , 60 , 60 , 60 , 60 , 60 } } ,
{ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 16 , 24 , 32 , 40 , 48 , 48 , 48 , 48 , 48 , 48 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 4 , 20 , 28 , 36 , 44 , 56 , 56 , 56 , 56 , 56 , 56 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 20 , 40 , 48 , 60 , 60 , 60 , 60 , 60 , 60 , 60 , 60 } } ,
{ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 12 , 24 , 32 , 48 , 48 , 48 , 48 , 48 , 48 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 16 , 28 , 36 , 56 , 56 , 56 , 56 , 56 , 56 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 32 , 48 , 60 , 60 , 60 , 60 , 60 , 60 , 60 } } ,
{ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 8 , 20 , 32 , 40 , 48 , 48 , 48 , 48 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 12 , 24 , 36 , 44 , 56 , 56 , 56 , 56 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 28 , 44 , 60 , 60 , 60 , 60 , 60 , 60 } }
} ;
2011-05-23 15:45:51 +00:00
/**
* LUT to select the coupling start band based on the bit rate , sample rate , and
* number of full - bandwidth channels . - 1 = coupling off
* ac3_coupling_start_tab [ channel_mode - 2 ] [ sample rate code ] [ bit rate code ]
*
* TODO : more testing for optimal parameters .
* multi - channel tests at 44.1 kHz and 32 kHz .
*/
static const int8_t ac3_coupling_start_tab [ 6 ] [ 3 ] [ 19 ] = {
// 32 40 48 56 64 80 96 112 128 160 192 224 256 320 384 448 512 576 640
// 2/0
{ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 7 , 8 , 11 , 12 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 1 , 3 , 5 , 7 , 10 , 12 , 13 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 } ,
{ 0 , 0 , 0 , 0 , 1 , 2 , 2 , 9 , 13 , 15 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 } } ,
// 3/0
{ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 , 2 , 6 , 9 , 11 , 12 , 13 , - 1 , - 1 , - 1 , - 1 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 , 2 , 6 , 9 , 11 , 12 , 13 , - 1 , - 1 , - 1 , - 1 } ,
{ - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 } } ,
// 2/1 - untested
{ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 , 2 , 6 , 9 , 11 , 12 , 13 , - 1 , - 1 , - 1 , - 1 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 , 2 , 6 , 9 , 11 , 12 , 13 , - 1 , - 1 , - 1 , - 1 } ,
{ - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 } } ,
// 3/1
{ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 2 , 10 , 11 , 11 , 12 , 12 , 14 , - 1 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 2 , 10 , 11 , 11 , 12 , 12 , 14 , - 1 } ,
{ - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 } } ,
// 2/2 - untested
{ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 2 , 10 , 11 , 11 , 12 , 12 , 14 , - 1 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 2 , 10 , 11 , 11 , 12 , 12 , 14 , - 1 } ,
{ - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 } } ,
// 3/2
{ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 6 , 8 , 11 , 12 , 12 , - 1 , - 1 } ,
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 6 , 8 , 11 , 12 , 12 , - 1 , - 1 } ,
{ - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 } } ,
} ;
2010-12-14 14:53:06 +00:00
/**
* Adjust the frame size to make the average bit rate match the target bit rate .
2011-05-24 19:20:56 +00:00
* This is only needed for 11025 , 22050 , and 44100 sample rates or any E - AC - 3.
2011-11-02 14:38:10 +00:00
*
* @ param s AC - 3 encoder private context
2010-12-14 14:53:06 +00:00
*/
2011-06-27 03:58:19 +00:00
void ff_ac3_adjust_frame_size ( AC3EncodeContext * s )
2010-12-14 14:53:06 +00:00
{
while ( s - > bits_written > = s - > bit_rate & & s - > samples_written > = s - > sample_rate ) {
s - > bits_written - = s - > bit_rate ;
s - > samples_written - = s - > sample_rate ;
}
2010-12-15 17:28:44 +00:00
s - > frame_size = s - > frame_size_min +
2 * ( s - > bits_written * s - > sample_rate < s - > samples_written * s - > bit_rate ) ;
2010-12-14 14:53:06 +00:00
s - > bits_written + = s - > frame_size * 8 ;
2011-07-14 17:02:45 +00:00
s - > samples_written + = AC3_BLOCK_SIZE * s - > num_blocks ;
2010-12-14 14:53:06 +00:00
}
2011-11-02 14:38:10 +00:00
/**
* Set the initial coupling strategy parameters prior to coupling analysis .
*
* @ param s AC - 3 encoder private context
*/
2011-06-27 03:58:19 +00:00
void ff_ac3_compute_coupling_strategy ( AC3EncodeContext * s )
2011-05-23 15:45:51 +00:00
{
int blk , ch ;
int got_cpl_snr ;
2011-07-13 16:20:29 +00:00
int num_cpl_blocks ;
2011-05-23 15:45:51 +00:00
/* set coupling use flags for each block/channel */
/* TODO: turn coupling on/off and adjust start band based on bit usage */
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2011-05-23 15:45:51 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
for ( ch = 1 ; ch < = s - > fbw_channels ; ch + + )
block - > channel_in_cpl [ ch ] = s - > cpl_on ;
}
/* enable coupling for each block if at least 2 channels have coupling
enabled for that block */
got_cpl_snr = 0 ;
2011-07-13 16:20:29 +00:00
num_cpl_blocks = 0 ;
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2011-05-23 15:45:51 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
block - > num_cpl_channels = 0 ;
for ( ch = 1 ; ch < = s - > fbw_channels ; ch + + )
block - > num_cpl_channels + = block - > channel_in_cpl [ ch ] ;
block - > cpl_in_use = block - > num_cpl_channels > 1 ;
2011-07-13 16:20:29 +00:00
num_cpl_blocks + = block - > cpl_in_use ;
2011-05-23 15:45:51 +00:00
if ( ! block - > cpl_in_use ) {
block - > num_cpl_channels = 0 ;
for ( ch = 1 ; ch < = s - > fbw_channels ; ch + + )
block - > channel_in_cpl [ ch ] = 0 ;
}
block - > new_cpl_strategy = ! blk ;
if ( blk ) {
for ( ch = 1 ; ch < = s - > fbw_channels ; ch + + ) {
if ( block - > channel_in_cpl [ ch ] ! = s - > blocks [ blk - 1 ] . channel_in_cpl [ ch ] ) {
block - > new_cpl_strategy = 1 ;
break ;
}
}
}
block - > new_cpl_leak = block - > new_cpl_strategy ;
if ( ! blk | | ( block - > cpl_in_use & & ! got_cpl_snr ) ) {
block - > new_snr_offsets = 1 ;
if ( block - > cpl_in_use )
got_cpl_snr = 1 ;
} else {
block - > new_snr_offsets = 0 ;
}
}
2011-07-13 16:20:29 +00:00
if ( ! num_cpl_blocks )
s - > cpl_on = 0 ;
2011-05-23 15:45:51 +00:00
/* set bandwidth for each channel */
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2011-05-23 15:45:51 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
for ( ch = 1 ; ch < = s - > fbw_channels ; ch + + ) {
if ( block - > channel_in_cpl [ ch ] )
block - > end_freq [ ch ] = s - > start_freq [ CPL_CH ] ;
else
block - > end_freq [ ch ] = s - > bandwidth_code * 3 + 73 ;
}
}
}
2011-01-08 23:21:17 +00:00
/**
* Apply stereo rematrixing to coefficients based on rematrixing flags .
2011-11-02 14:38:10 +00:00
*
* @ param s AC - 3 encoder private context
2011-01-08 23:21:17 +00:00
*/
2022-05-23 03:23:35 +00:00
static void ac3_apply_rematrixing ( AC3EncodeContext * s )
2011-01-08 23:21:17 +00:00
{
int nb_coefs ;
int blk , bnd , i ;
int start , end ;
2012-11-04 17:47:20 +00:00
uint8_t * flags = NULL ;
2011-01-08 23:21:17 +00:00
2011-04-15 23:22:42 +00:00
if ( ! s - > rematrixing_enabled )
2011-01-08 23:21:17 +00:00
return ;
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2011-01-08 23:21:17 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
if ( block - > new_rematrixing_strategy )
flags = block - > rematrixing_flags ;
2011-05-23 15:45:51 +00:00
nb_coefs = FFMIN ( block - > end_freq [ 1 ] , block - > end_freq [ 2 ] ) ;
for ( bnd = 0 ; bnd < block - > num_rematrixing_bands ; bnd + + ) {
2011-01-08 23:21:17 +00:00
if ( flags [ bnd ] ) {
start = ff_ac3_rematrix_band_tab [ bnd ] ;
end = FFMIN ( nb_coefs , ff_ac3_rematrix_band_tab [ bnd + 1 ] ) ;
for ( i = start ; i < end ; i + + ) {
2011-05-23 15:45:51 +00:00
int32_t lt = block - > fixed_coef [ 1 ] [ i ] ;
int32_t rt = block - > fixed_coef [ 2 ] [ i ] ;
block - > fixed_coef [ 1 ] [ i ] = ( lt + rt ) > > 1 ;
block - > fixed_coef [ 2 ] [ i ] = ( lt - rt ) > > 1 ;
2011-01-08 23:21:17 +00:00
}
}
}
}
}
2011-11-02 14:38:10 +00:00
/*
2010-12-16 21:09:22 +00:00
* Initialize exponent tables .
*/
2022-05-23 03:23:35 +00:00
static av_cold void exponent_init ( void )
2010-12-16 21:09:22 +00:00
{
2011-04-15 23:51:06 +00:00
int expstr , i , grpsize ;
for ( expstr = EXP_D15 - 1 ; expstr < = EXP_D45 - 1 ; expstr + + ) {
grpsize = 3 < < expstr ;
2011-05-23 15:45:51 +00:00
for ( i = 12 ; i < 256 ; i + + ) {
exponent_group_tab [ 0 ] [ expstr ] [ i ] = ( i + grpsize - 4 ) / grpsize ;
exponent_group_tab [ 1 ] [ expstr ] [ i ] = ( i ) / grpsize ;
2011-04-15 23:51:06 +00:00
}
2010-12-16 21:09:22 +00:00
}
2010-12-17 22:06:00 +00:00
/* LFE */
2011-05-23 15:45:51 +00:00
exponent_group_tab [ 0 ] [ 0 ] [ 7 ] = 2 ;
2010-12-16 21:09:22 +00:00
}
2011-11-02 14:38:10 +00:00
/*
2010-12-14 14:53:02 +00:00
* Extract exponents from the MDCT coefficients .
*/
2010-12-14 22:45:31 +00:00
static void extract_exponents ( AC3EncodeContext * s )
2010-12-14 14:53:02 +00:00
{
2011-06-01 16:40:01 +00:00
int ch = ! s - > cpl_on ;
2011-07-14 17:02:45 +00:00
int chan_size = AC3_MAX_COEFS * s - > num_blocks * ( s - > channels - ch + 1 ) ;
2011-06-01 16:40:01 +00:00
AC3Block * block = & s - > blocks [ 0 ] ;
2010-12-14 14:53:02 +00:00
2011-06-01 16:40:01 +00:00
s - > ac3dsp . extract_exponents ( block - > exp [ ch ] , block - > fixed_coef [ ch ] , chan_size ) ;
2010-12-14 14:53:02 +00:00
}
2010-12-14 14:51:30 +00:00
/**
* Exponent Difference Threshold .
* New exponents are sent if their SAD exceed this number .
*/
2011-02-02 18:23:59 +00:00
# define EXP_DIFF_THRESHOLD 500
2010-12-14 14:51:09 +00:00
2011-07-14 17:02:45 +00:00
/**
* Table used to select exponent strategy based on exponent reuse block interval .
*/
static const uint8_t exp_strategy_reuse_tab [ 4 ] [ 6 ] = {
{ EXP_D15 , EXP_D15 , EXP_D15 , EXP_D15 , EXP_D15 , EXP_D15 } ,
{ EXP_D15 , EXP_D15 , EXP_D15 , EXP_D15 , EXP_D15 , EXP_D15 } ,
{ EXP_D25 , EXP_D25 , EXP_D15 , EXP_D15 , EXP_D15 , EXP_D15 } ,
{ EXP_D45 , EXP_D25 , EXP_D25 , EXP_D15 , EXP_D15 , EXP_D15 }
} ;
2010-12-14 14:51:26 +00:00
2011-11-02 14:38:10 +00:00
/*
2010-12-14 14:53:02 +00:00
* Calculate exponent strategies for all channels .
2010-12-14 14:53:17 +00:00
* Array arrangement is reversed to simplify the per - channel calculation .
2010-12-14 14:53:02 +00:00
*/
2010-12-14 22:45:31 +00:00
static void compute_exp_strategy ( AC3EncodeContext * s )
2010-12-14 14:53:02 +00:00
{
2011-04-16 02:43:25 +00:00
int ch , blk , blk1 ;
2010-12-14 14:53:02 +00:00
2011-05-23 15:45:51 +00:00
for ( ch = ! s - > cpl_on ; ch < = s - > fbw_channels ; ch + + ) {
2011-04-16 02:43:25 +00:00
uint8_t * exp_strategy = s - > exp_strategy [ ch ] ;
uint8_t * exp = s - > blocks [ 0 ] . exp [ ch ] ;
int exp_diff ;
/* estimate if the exponent variation & decide if they should be
reused in the next frame */
exp_strategy [ 0 ] = EXP_NEW ;
exp + = AC3_MAX_COEFS ;
2011-07-14 17:02:45 +00:00
for ( blk = 1 ; blk < s - > num_blocks ; blk + + , exp + = AC3_MAX_COEFS ) {
2011-07-13 16:20:29 +00:00
if ( ch = = CPL_CH ) {
if ( ! s - > blocks [ blk - 1 ] . cpl_in_use ) {
exp_strategy [ blk ] = EXP_NEW ;
continue ;
} else if ( ! s - > blocks [ blk ] . cpl_in_use ) {
exp_strategy [ blk ] = EXP_REUSE ;
continue ;
}
} else if ( s - > blocks [ blk ] . channel_in_cpl [ ch ] ! = s - > blocks [ blk - 1 ] . channel_in_cpl [ ch ] ) {
2011-05-23 15:45:51 +00:00
exp_strategy [ blk ] = EXP_NEW ;
continue ;
}
2014-02-08 01:59:58 +00:00
exp_diff = s - > mecc . sad [ 0 ] ( NULL , exp , exp - AC3_MAX_COEFS , 16 , 16 ) ;
2011-05-23 15:45:51 +00:00
exp_strategy [ blk ] = EXP_REUSE ;
if ( ch = = CPL_CH & & exp_diff > ( EXP_DIFF_THRESHOLD * ( s - > blocks [ blk ] . end_freq [ ch ] - s - > start_freq [ ch ] ) / AC3_MAX_COEFS ) )
exp_strategy [ blk ] = EXP_NEW ;
else if ( ch > CPL_CH & & exp_diff > EXP_DIFF_THRESHOLD )
2011-04-16 02:43:25 +00:00
exp_strategy [ blk ] = EXP_NEW ;
}
/* now select the encoding strategy type : if exponents are often
recoded , we use a coarse encoding */
blk = 0 ;
2011-07-14 17:02:45 +00:00
while ( blk < s - > num_blocks ) {
2011-04-16 02:43:25 +00:00
blk1 = blk + 1 ;
2011-07-14 17:02:45 +00:00
while ( blk1 < s - > num_blocks & & exp_strategy [ blk1 ] = = EXP_REUSE )
2011-04-16 02:43:25 +00:00
blk1 + + ;
2011-07-14 17:02:45 +00:00
exp_strategy [ blk ] = exp_strategy_reuse_tab [ s - > num_blks_code ] [ blk1 - blk - 1 ] ;
2011-04-16 02:43:25 +00:00
blk = blk1 ;
}
2010-12-14 14:53:17 +00:00
}
if ( s - > lfe_on ) {
ch = s - > lfe_channel ;
2011-01-15 01:58:50 +00:00
s - > exp_strategy [ ch ] [ 0 ] = EXP_D15 ;
2011-07-14 17:02:45 +00:00
for ( blk = 1 ; blk < s - > num_blocks ; blk + + )
2011-01-15 01:58:50 +00:00
s - > exp_strategy [ ch ] [ blk ] = EXP_REUSE ;
2010-12-14 14:53:02 +00:00
}
2011-07-13 16:20:29 +00:00
/* for E-AC-3, determine frame exponent strategy */
if ( CONFIG_EAC3_ENCODER & & s - > eac3 )
ff_eac3_get_frame_exp_strategy ( s ) ;
2010-12-14 14:53:02 +00:00
}
2010-12-14 14:51:30 +00:00
/**
* Update the exponents so that they are the ones the decoder will decode .
2011-11-02 14:38:10 +00:00
*
* @ param [ in , out ] exp array of exponents for 1 block in 1 channel
* @ param nb_exps number of exponents in active bandwidth
* @ param exp_strategy exponent strategy for the block
* @ param cpl indicates if the block is in the coupling channel
2010-12-14 14:51:30 +00:00
*/
2011-05-23 15:45:51 +00:00
static void encode_exponents_blk_ch ( uint8_t * exp , int nb_exps , int exp_strategy ,
int cpl )
2001-07-22 14:18:56 +00:00
{
2010-12-16 21:09:22 +00:00
int nb_groups , i , k ;
2001-07-22 14:18:56 +00:00
2011-05-23 15:45:51 +00:00
nb_groups = exponent_group_tab [ cpl ] [ exp_strategy - 1 ] [ nb_exps ] * 3 ;
2001-07-22 14:18:56 +00:00
/* for each group, compute the minimum exponent */
2010-12-16 21:09:16 +00:00
switch ( exp_strategy ) {
case EXP_D25 :
2011-05-23 15:45:51 +00:00
for ( i = 1 , k = 1 - cpl ; i < = nb_groups ; i + + ) {
2010-12-16 21:09:16 +00:00
uint8_t exp_min = exp [ k ] ;
if ( exp [ k + 1 ] < exp_min )
exp_min = exp [ k + 1 ] ;
2011-05-23 15:45:51 +00:00
exp [ i - cpl ] = exp_min ;
2010-12-16 21:09:16 +00:00
k + = 2 ;
2001-07-22 14:18:56 +00:00
}
2010-12-16 21:09:16 +00:00
break ;
case EXP_D45 :
2011-05-23 15:45:51 +00:00
for ( i = 1 , k = 1 - cpl ; i < = nb_groups ; i + + ) {
2010-12-16 21:09:16 +00:00
uint8_t exp_min = exp [ k ] ;
if ( exp [ k + 1 ] < exp_min )
exp_min = exp [ k + 1 ] ;
if ( exp [ k + 2 ] < exp_min )
exp_min = exp [ k + 2 ] ;
if ( exp [ k + 3 ] < exp_min )
exp_min = exp [ k + 3 ] ;
2011-05-23 15:45:51 +00:00
exp [ i - cpl ] = exp_min ;
2010-12-16 21:09:16 +00:00
k + = 4 ;
}
break ;
2010-12-16 21:09:02 +00:00
}
2001-07-22 14:18:56 +00:00
/* constraint for DC exponent */
2011-05-23 15:45:51 +00:00
if ( ! cpl & & exp [ 0 ] > 15 )
2010-12-16 21:09:02 +00:00
exp [ 0 ] = 15 ;
2001-07-22 14:18:56 +00:00
2010-12-14 14:51:09 +00:00
/* decrease the delta between each groups to within 2 so that they can be
differentially encoded */
for ( i = 1 ; i < = nb_groups ; i + + )
2010-12-16 21:09:02 +00:00
exp [ i ] = FFMIN ( exp [ i ] , exp [ i - 1 ] + 2 ) ;
2010-12-16 21:09:08 +00:00
i - - ;
while ( - - i > = 0 )
2010-12-16 21:09:02 +00:00
exp [ i ] = FFMIN ( exp [ i ] , exp [ i + 1 ] + 2 ) ;
2004-08-02 10:42:21 +00:00
2011-05-23 15:45:51 +00:00
if ( cpl )
exp [ - 1 ] = exp [ 0 ] & ~ 1 ;
2001-07-22 14:18:56 +00:00
/* now we have the exponent values the decoder will see */
2010-12-16 21:09:16 +00:00
switch ( exp_strategy ) {
case EXP_D25 :
2011-05-23 15:45:51 +00:00
for ( i = nb_groups , k = ( nb_groups * 2 ) - cpl ; i > 0 ; i - - ) {
uint8_t exp1 = exp [ i - cpl ] ;
2010-12-16 21:09:16 +00:00
exp [ k - - ] = exp1 ;
exp [ k - - ] = exp1 ;
}
break ;
case EXP_D45 :
2011-05-23 15:45:51 +00:00
for ( i = nb_groups , k = ( nb_groups * 4 ) - cpl ; i > 0 ; i - - ) {
exp [ k ] = exp [ k - 1 ] = exp [ k - 2 ] = exp [ k - 3 ] = exp [ i - cpl ] ;
2010-12-16 21:09:16 +00:00
k - = 4 ;
}
break ;
2001-07-22 14:18:56 +00:00
}
}
2010-12-14 14:51:26 +00:00
2011-11-02 14:38:10 +00:00
/*
2010-12-14 14:53:02 +00:00
* Encode exponents from original extracted form to what the decoder will see .
* This copies and groups exponents based on exponent strategy and reduces
* deltas between adjacent exponent groups so that they can be differentially
* encoded .
*/
2010-12-14 22:45:31 +00:00
static void encode_exponents ( AC3EncodeContext * s )
2010-12-14 14:53:02 +00:00
{
2011-05-23 15:45:51 +00:00
int blk , blk1 , ch , cpl ;
2011-03-28 18:01:27 +00:00
uint8_t * exp , * exp_strategy ;
2011-01-15 01:59:21 +00:00
int nb_coefs , num_reuse_blocks ;
2010-12-14 14:53:02 +00:00
2011-05-23 15:45:51 +00:00
for ( ch = ! s - > cpl_on ; ch < = s - > channels ; ch + + ) {
exp = s - > blocks [ 0 ] . exp [ ch ] + s - > start_freq [ ch ] ;
2011-01-15 01:59:15 +00:00
exp_strategy = s - > exp_strategy [ ch ] ;
2011-05-23 15:45:51 +00:00
cpl = ( ch = = CPL_CH ) ;
2010-12-14 14:53:02 +00:00
blk = 0 ;
2011-07-14 17:02:45 +00:00
while ( blk < s - > num_blocks ) {
2011-05-23 15:45:51 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
if ( cpl & & ! block - > cpl_in_use ) {
exp + = AC3_MAX_COEFS ;
blk + + ;
continue ;
}
nb_coefs = block - > end_freq [ ch ] - s - > start_freq [ ch ] ;
2010-12-14 14:53:02 +00:00
blk1 = blk + 1 ;
2011-01-15 01:59:21 +00:00
2011-03-28 18:01:27 +00:00
/* count the number of EXP_REUSE blocks after the current block
2011-05-26 19:57:21 +00:00
and set exponent reference block numbers */
s - > exp_ref_block [ ch ] [ blk ] = blk ;
2011-07-14 17:02:45 +00:00
while ( blk1 < s - > num_blocks & & exp_strategy [ blk1 ] = = EXP_REUSE ) {
2011-05-26 19:57:21 +00:00
s - > exp_ref_block [ ch ] [ blk1 ] = blk ;
2010-12-14 14:53:02 +00:00
blk1 + + ;
2011-03-28 18:01:27 +00:00
}
2011-01-15 01:59:21 +00:00
num_reuse_blocks = blk1 - blk - 1 ;
/* for the EXP_REUSE case we select the min of the exponents */
2011-05-23 15:45:51 +00:00
s - > ac3dsp . ac3_exponent_min ( exp - s - > start_freq [ ch ] , num_reuse_blocks ,
AC3_MAX_COEFS ) ;
2011-01-15 01:59:21 +00:00
2011-05-23 15:45:51 +00:00
encode_exponents_blk_ch ( exp , nb_coefs , exp_strategy [ blk ] , cpl ) ;
2011-01-15 01:59:31 +00:00
2011-03-28 18:01:27 +00:00
exp + = AC3_MAX_COEFS * ( num_reuse_blocks + 1 ) ;
2010-12-14 14:53:02 +00:00
blk = blk1 ;
}
}
2011-05-26 19:57:21 +00:00
/* reference block numbers have been changed, so reset ref_bap_set */
s - > ref_bap_set = 0 ;
2010-12-14 14:53:26 +00:00
}
2011-11-02 14:38:10 +00:00
/*
2011-08-05 20:00:18 +00:00
* Count exponent bits based on bandwidth , coupling , and exponent strategies .
*/
static int count_exponent_bits ( AC3EncodeContext * s )
{
int blk , ch ;
int nb_groups , bit_count ;
bit_count = 0 ;
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
AC3Block * block = & s - > blocks [ blk ] ;
for ( ch = ! block - > cpl_in_use ; ch < = s - > channels ; ch + + ) {
int exp_strategy = s - > exp_strategy [ ch ] [ blk ] ;
int cpl = ( ch = = CPL_CH ) ;
int nb_coefs = block - > end_freq [ ch ] - s - > start_freq [ ch ] ;
if ( exp_strategy = = EXP_REUSE )
continue ;
nb_groups = exponent_group_tab [ cpl ] [ exp_strategy - 1 ] [ nb_coefs ] ;
bit_count + = 4 + ( nb_groups * 7 ) ;
}
}
return bit_count ;
}
2010-12-14 14:53:26 +00:00
/**
* Group exponents .
* 3 delta - encoded exponents are in each 7 - bit group . The number of groups
* varies depending on exponent strategy and bandwidth .
2011-11-02 14:38:10 +00:00
*
* @ param s AC - 3 encoder private context
2010-12-14 14:53:26 +00:00
*/
2022-05-23 03:23:35 +00:00
static void ac3_group_exponents ( AC3EncodeContext * s )
2010-12-14 14:53:26 +00:00
{
2011-05-23 15:45:51 +00:00
int blk , ch , i , cpl ;
2011-08-05 20:00:18 +00:00
int group_size , nb_groups ;
2010-12-14 14:53:26 +00:00
uint8_t * p ;
int delta0 , delta1 , delta2 ;
int exp0 , exp1 ;
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2010-12-15 17:28:41 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
2011-05-23 15:45:51 +00:00
for ( ch = ! block - > cpl_in_use ; ch < = s - > channels ; ch + + ) {
2011-01-15 01:59:04 +00:00
int exp_strategy = s - > exp_strategy [ ch ] [ blk ] ;
if ( exp_strategy = = EXP_REUSE )
2010-12-14 14:53:26 +00:00
continue ;
2011-05-23 15:45:51 +00:00
cpl = ( ch = = CPL_CH ) ;
2011-01-15 01:59:04 +00:00
group_size = exp_strategy + ( exp_strategy = = EXP_D45 ) ;
2011-05-23 15:45:51 +00:00
nb_groups = exponent_group_tab [ cpl ] [ exp_strategy - 1 ] [ block - > end_freq [ ch ] - s - > start_freq [ ch ] ] ;
p = block - > exp [ ch ] + s - > start_freq [ ch ] - cpl ;
2010-12-14 14:53:26 +00:00
/* DC exponent */
exp1 = * p + + ;
2010-12-15 17:28:41 +00:00
block - > grouped_exp [ ch ] [ 0 ] = exp1 ;
2010-12-14 14:53:26 +00:00
/* remaining exponents are delta encoded */
2010-12-16 21:09:22 +00:00
for ( i = 1 ; i < = nb_groups ; i + + ) {
2010-12-14 14:53:26 +00:00
/* merge three delta in one code */
exp0 = exp1 ;
exp1 = p [ 0 ] ;
p + = group_size ;
delta0 = exp1 - exp0 + 2 ;
2011-03-04 17:12:01 +00:00
av_assert2 ( delta0 > = 0 & & delta0 < = 4 ) ;
2010-12-14 14:53:26 +00:00
exp0 = exp1 ;
exp1 = p [ 0 ] ;
p + = group_size ;
delta1 = exp1 - exp0 + 2 ;
2011-03-04 17:12:01 +00:00
av_assert2 ( delta1 > = 0 & & delta1 < = 4 ) ;
2010-12-14 14:53:26 +00:00
exp0 = exp1 ;
exp1 = p [ 0 ] ;
p + = group_size ;
delta2 = exp1 - exp0 + 2 ;
2011-03-04 17:12:01 +00:00
av_assert2 ( delta2 > = 0 & & delta2 < = 4 ) ;
2010-12-14 14:53:26 +00:00
2010-12-15 17:28:41 +00:00
block - > grouped_exp [ ch ] [ i ] = ( ( delta0 * 5 + delta1 ) * 5 ) + delta2 ;
2010-12-14 14:53:26 +00:00
}
}
}
2010-12-14 14:53:02 +00:00
}
/**
* Calculate final exponents from the supplied MDCT coefficients and exponent shift .
* Extract exponents from MDCT coefficients , calculate exponent strategies ,
* and encode final exponents .
2011-11-02 14:38:10 +00:00
*
* @ param s AC - 3 encoder private context
2010-12-14 14:53:02 +00:00
*/
2022-05-23 03:23:35 +00:00
static void ac3_process_exponents ( AC3EncodeContext * s )
2010-12-14 14:53:02 +00:00
{
2010-12-14 22:45:31 +00:00
extract_exponents ( s ) ;
2010-12-14 14:53:02 +00:00
2010-12-14 22:45:31 +00:00
compute_exp_strategy ( s ) ;
2010-12-14 14:53:02 +00:00
2010-12-14 22:45:31 +00:00
encode_exponents ( s ) ;
2010-12-14 14:53:26 +00:00
2011-02-10 17:20:36 +00:00
emms_c ( ) ;
2010-12-14 14:53:02 +00:00
}
2011-11-02 14:38:10 +00:00
/*
2010-12-16 22:47:00 +00:00
* Count frame bits that are based solely on fixed parameters .
* This only has to be run once when the encoder is initialized .
*/
static void count_frame_bits_fixed ( AC3EncodeContext * s )
{
2019-06-19 02:39:47 +00:00
static const uint8_t frame_bits_inc [ 8 ] = { 0 , 0 , 2 , 2 , 2 , 4 , 2 , 4 } ;
2010-12-16 22:47:00 +00:00
int blk ;
int frame_bits ;
/* assumptions:
* no dynamic range codes
* bit allocation parameters do not change between blocks
* no delta bit allocation
* no skipped data
2012-12-19 17:48:21 +00:00
* no auxiliary data
2011-05-24 19:20:56 +00:00
* no E - AC - 3 metadata
2010-12-16 22:47:00 +00:00
*/
2011-04-30 19:52:55 +00:00
/* header */
2011-05-24 19:20:56 +00:00
frame_bits = 16 ; /* sync info */
if ( s - > eac3 ) {
/* bitstream info header */
frame_bits + = 35 ;
2011-07-14 17:02:45 +00:00
frame_bits + = 1 + 1 ;
if ( s - > num_blocks ! = 0x6 )
frame_bits + + ;
frame_bits + + ;
2011-05-24 19:20:56 +00:00
/* audio frame header */
2011-07-14 17:02:45 +00:00
if ( s - > num_blocks = = 6 )
frame_bits + = 2 ;
2011-05-24 19:20:56 +00:00
frame_bits + = 10 ;
/* exponent strategy */
2011-07-13 16:20:29 +00:00
if ( s - > use_frame_exp_strategy )
frame_bits + = 5 * s - > fbw_channels ;
else
2011-07-14 17:02:45 +00:00
frame_bits + = s - > num_blocks * 2 * s - > fbw_channels ;
2011-07-13 16:20:29 +00:00
if ( s - > lfe_on )
2011-07-14 17:02:45 +00:00
frame_bits + = s - > num_blocks ;
2011-05-24 19:20:56 +00:00
/* converter exponent strategy */
2011-07-14 17:02:45 +00:00
if ( s - > num_blks_code ! = 0x3 )
frame_bits + + ;
else
frame_bits + = s - > fbw_channels * 5 ;
2011-05-24 19:20:56 +00:00
/* snr offsets */
frame_bits + = 10 ;
/* block start info */
2011-07-14 17:02:45 +00:00
if ( s - > num_blocks ! = 1 )
frame_bits + + ;
2011-05-24 19:20:56 +00:00
} else {
frame_bits + = 49 ;
frame_bits + = frame_bits_inc [ s - > channel_mode ] ;
}
2010-12-16 22:47:00 +00:00
/* audio blocks */
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 ) {
2011-05-24 23:38:30 +00:00
/* block switch flags */
frame_bits + = s - > fbw_channels ;
2011-04-30 19:52:55 +00:00
2011-05-24 23:38:30 +00:00
/* dither flags */
frame_bits + = s - > fbw_channels ;
2011-05-24 19:20:56 +00:00
}
2011-04-30 19:52:55 +00:00
/* dynamic range */
frame_bits + + ;
2011-05-24 19:20:56 +00:00
/* spectral extension */
if ( s - > eac3 )
2011-04-30 19:52:55 +00:00
frame_bits + + ;
2024-04-25 09:18:18 +00:00
/* coupling strategy exists: cplstre */
if ( ! s - > eac3 )
frame_bits + + ;
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 ) {
2011-05-24 23:38:30 +00:00
/* exponent strategy */
frame_bits + = 2 * s - > fbw_channels ;
if ( s - > lfe_on )
frame_bits + + ;
2011-04-30 19:52:55 +00:00
2011-05-24 23:38:30 +00:00
/* bit allocation params */
frame_bits + + ;
if ( ! blk )
frame_bits + = 2 + 2 + 2 + 2 + 3 ;
2011-05-24 19:20:56 +00:00
}
2011-04-30 19:52:55 +00:00
2024-04-25 09:18:18 +00:00
/* snroffste for AC-3, convsnroffste for E-AC-3 */
frame_bits + + ;
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 ) {
2011-05-24 23:38:30 +00:00
/* delta bit allocation */
frame_bits + + ;
2011-04-30 19:52:55 +00:00
2011-05-24 23:38:30 +00:00
/* skipped data */
frame_bits + + ;
2011-05-24 19:20:56 +00:00
}
2010-12-16 22:47:00 +00:00
}
2011-04-30 19:52:55 +00:00
/* auxiliary data */
frame_bits + + ;
2010-12-16 22:47:00 +00:00
/* CRC */
2011-04-30 19:52:55 +00:00
frame_bits + = 1 + 16 ;
2010-12-16 22:47:00 +00:00
s - > frame_bits_fixed = frame_bits ;
}
2011-11-02 14:38:10 +00:00
/*
2010-12-14 14:53:43 +00:00
* Initialize bit allocation .
* Set default parameter codes and calculate parameter values .
*/
2013-02-01 09:31:59 +00:00
static av_cold void bit_alloc_init ( AC3EncodeContext * s )
2010-12-14 14:53:43 +00:00
{
int ch ;
/* init default parameters */
s - > slow_decay_code = 2 ;
s - > fast_decay_code = 1 ;
s - > slow_gain_code = 1 ;
2011-05-24 19:20:56 +00:00
s - > db_per_bit_code = s - > eac3 ? 2 : 3 ;
2011-02-15 18:46:56 +00:00
s - > floor_code = 7 ;
2011-05-23 15:45:51 +00:00
for ( ch = 0 ; ch < = s - > channels ; ch + + )
2010-12-14 14:53:43 +00:00
s - > fast_gain_code [ ch ] = 4 ;
/* initial snr offset */
s - > coarse_snr_offset = 40 ;
/* compute real values */
/* currently none of these values change during encoding, so we can just
set them once at initialization */
s - > bit_alloc . slow_decay = ff_ac3_slow_decay_tab [ s - > slow_decay_code ] > > s - > bit_alloc . sr_shift ;
s - > bit_alloc . fast_decay = ff_ac3_fast_decay_tab [ s - > fast_decay_code ] > > s - > bit_alloc . sr_shift ;
s - > bit_alloc . slow_gain = ff_ac3_slow_gain_tab [ s - > slow_gain_code ] ;
s - > bit_alloc . db_per_bit = ff_ac3_db_per_bit_tab [ s - > db_per_bit_code ] ;
s - > bit_alloc . floor = ff_ac3_floor_tab [ s - > floor_code ] ;
2011-05-23 15:45:51 +00:00
s - > bit_alloc . cpl_fast_leak = 0 ;
s - > bit_alloc . cpl_slow_leak = 0 ;
2010-12-16 22:47:00 +00:00
count_frame_bits_fixed ( s ) ;
2010-12-14 14:53:43 +00:00
}
2011-11-02 14:38:10 +00:00
/*
2010-12-14 14:53:40 +00:00
* Count the bits used to encode the frame , minus exponents and mantissas .
2010-12-16 22:47:00 +00:00
* Bits based on fixed parameters have already been counted , so now we just
* have to add the bits based on parameters that change during encoding .
2010-12-14 14:53:40 +00:00
*/
2010-12-14 22:45:31 +00:00
static void count_frame_bits ( AC3EncodeContext * s )
2010-12-14 14:53:40 +00:00
{
2011-03-25 21:12:26 +00:00
AC3EncOptions * opt = & s - > options ;
2010-12-14 14:53:40 +00:00
int blk , ch ;
2010-12-16 22:47:00 +00:00
int frame_bits = 0 ;
2010-12-14 14:53:40 +00:00
2011-04-30 19:52:55 +00:00
/* header */
2011-05-24 19:20:56 +00:00
if ( s - > eac3 ) {
2011-05-29 23:16:46 +00:00
if ( opt - > eac3_mixing_metadata ) {
if ( s - > channel_mode > AC3_CHMODE_STEREO )
frame_bits + = 2 ;
if ( s - > has_center )
frame_bits + = 6 ;
if ( s - > has_surround )
frame_bits + = 6 ;
frame_bits + = s - > lfe_on ;
frame_bits + = 1 + 1 + 2 ;
if ( s - > channel_mode < AC3_CHMODE_STEREO )
frame_bits + + ;
frame_bits + + ;
}
if ( opt - > eac3_info_metadata ) {
frame_bits + = 3 + 1 + 1 ;
if ( s - > channel_mode = = AC3_CHMODE_STEREO )
frame_bits + = 2 + 2 ;
if ( s - > channel_mode > = AC3_CHMODE_2F2R )
frame_bits + = 2 ;
frame_bits + + ;
if ( opt - > audio_production_info )
frame_bits + = 5 + 2 + 1 ;
frame_bits + + ;
}
2011-05-24 19:20:56 +00:00
/* coupling */
if ( s - > channel_mode > AC3_CHMODE_MONO ) {
frame_bits + + ;
2011-07-14 17:02:45 +00:00
for ( blk = 1 ; blk < s - > num_blocks ; blk + + ) {
2011-05-24 19:20:56 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
frame_bits + + ;
if ( block - > new_cpl_strategy )
frame_bits + + ;
}
}
/* coupling exponent strategy */
2011-07-13 16:20:29 +00:00
if ( s - > cpl_on ) {
if ( s - > use_frame_exp_strategy ) {
2024-04-25 09:18:18 +00:00
frame_bits + = 5 ;
2011-07-13 16:20:29 +00:00
} else {
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + )
2011-07-13 16:20:29 +00:00
frame_bits + = 2 * s - > blocks [ blk ] . cpl_in_use ;
}
}
2011-05-24 19:20:56 +00:00
} else {
2011-05-24 23:38:30 +00:00
if ( opt - > audio_production_info )
frame_bits + = 7 ;
if ( s - > bitstream_id = = 6 ) {
if ( opt - > extended_bsi_1 )
frame_bits + = 14 ;
if ( opt - > extended_bsi_2 )
frame_bits + = 14 ;
}
2011-03-25 21:12:26 +00:00
}
2011-04-30 19:52:55 +00:00
/* audio blocks */
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2011-05-23 15:45:51 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
/* coupling strategy */
if ( block - > new_cpl_strategy ) {
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 )
2011-05-24 23:38:30 +00:00
frame_bits + + ;
2011-05-23 15:45:51 +00:00
if ( block - > cpl_in_use ) {
2011-05-24 19:20:56 +00:00
if ( s - > eac3 )
frame_bits + + ;
if ( ! s - > eac3 | | s - > channel_mode ! = AC3_CHMODE_STEREO )
2011-05-24 23:38:30 +00:00
frame_bits + = s - > fbw_channels ;
2011-05-23 15:45:51 +00:00
if ( s - > channel_mode = = AC3_CHMODE_STEREO )
frame_bits + + ;
frame_bits + = 4 + 4 ;
2011-05-24 19:20:56 +00:00
if ( s - > eac3 )
frame_bits + + ;
else
2011-05-24 23:38:30 +00:00
frame_bits + = s - > num_cpl_subbands - 1 ;
2011-05-23 15:45:51 +00:00
}
}
/* coupling coordinates */
if ( block - > cpl_in_use ) {
for ( ch = 1 ; ch < = s - > fbw_channels ; ch + + ) {
if ( block - > channel_in_cpl [ ch ] ) {
2011-08-05 20:28:39 +00:00
if ( ! s - > eac3 | | block - > new_cpl_coords [ ch ] ! = 2 )
2011-05-24 23:38:30 +00:00
frame_bits + + ;
2011-08-05 20:28:39 +00:00
if ( block - > new_cpl_coords [ ch ] ) {
2011-05-23 15:45:51 +00:00
frame_bits + = 2 ;
frame_bits + = ( 4 + 4 ) * s - > num_cpl_bands ;
}
}
}
}
2011-01-08 23:21:17 +00:00
/* stereo rematrixing */
2011-04-30 19:55:18 +00:00
if ( s - > channel_mode = = AC3_CHMODE_STEREO ) {
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 | | blk > 0 )
2011-05-24 23:38:30 +00:00
frame_bits + + ;
2011-04-30 19:55:18 +00:00
if ( s - > blocks [ blk ] . new_rematrixing_strategy )
2011-05-23 15:45:51 +00:00
frame_bits + = block - > num_rematrixing_bands ;
2011-01-08 23:21:17 +00:00
}
2011-04-30 19:52:55 +00:00
/* bandwidth codes & gain range */
2011-05-23 15:45:51 +00:00
for ( ch = 1 ; ch < = s - > fbw_channels ; ch + + ) {
if ( s - > exp_strategy [ ch ] [ blk ] ! = EXP_REUSE ) {
if ( ! block - > channel_in_cpl [ ch ] )
frame_bits + = 6 ;
frame_bits + = 2 ;
}
}
/* coupling exponent strategy */
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 & & block - > cpl_in_use )
2011-05-23 15:45:51 +00:00
frame_bits + = 2 ;
/* snr offsets and fast gain codes */
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 ) {
2011-05-24 23:38:30 +00:00
if ( block - > new_snr_offsets )
frame_bits + = 6 + ( s - > channels + block - > cpl_in_use ) * ( 4 + 3 ) ;
2011-05-24 19:20:56 +00:00
}
2011-05-23 15:45:51 +00:00
/* coupling leak info */
if ( block - > cpl_in_use ) {
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 | | block - > new_cpl_leak ! = 2 )
2011-05-24 23:38:30 +00:00
frame_bits + + ;
2011-05-23 15:45:51 +00:00
if ( block - > new_cpl_leak )
frame_bits + = 3 + 3 ;
2010-12-14 14:53:40 +00:00
}
}
2011-04-30 19:52:55 +00:00
2010-12-16 22:47:00 +00:00
s - > frame_bits = s - > frame_bits_fixed + frame_bits ;
2010-12-14 14:53:40 +00:00
}
2011-11-02 14:38:10 +00:00
/*
2010-12-14 14:51:30 +00:00
* Calculate masking curve based on the final exponents .
* Also calculate the power spectral densities to use in future calculations .
*/
2010-12-14 22:45:31 +00:00
static void bit_alloc_masking ( AC3EncodeContext * s )
2007-03-22 05:34:26 +00:00
{
int blk , ch ;
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2010-12-15 17:28:41 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
2011-05-23 15:45:51 +00:00
for ( ch = ! block - > cpl_in_use ; ch < = s - > channels ; ch + + ) {
2010-12-17 14:16:13 +00:00
/* We only need psd and mask for calculating bap.
Since we currently do not calculate bap when exponent
strategy is EXP_REUSE we do not need to calculate psd or mask . */
2011-01-15 01:58:50 +00:00
if ( s - > exp_strategy [ ch ] [ blk ] ! = EXP_REUSE ) {
2011-05-23 15:45:51 +00:00
ff_ac3_bit_alloc_calc_psd ( block - > exp [ ch ] , s - > start_freq [ ch ] ,
block - > end_freq [ ch ] , block - > psd [ ch ] ,
block - > band_psd [ ch ] ) ;
2010-12-15 17:28:41 +00:00
ff_ac3_bit_alloc_calc_mask ( & s - > bit_alloc , block - > band_psd [ ch ] ,
2011-05-23 15:45:51 +00:00
s - > start_freq [ ch ] , block - > end_freq [ ch ] ,
2007-12-09 03:23:04 +00:00
ff_ac3_fast_gain_tab [ s - > fast_gain_code [ ch ] ] ,
2007-03-22 05:34:26 +00:00
ch = = s - > lfe_channel ,
2007-07-15 01:31:09 +00:00
DBA_NONE , 0 , NULL , NULL , NULL ,
2010-12-15 17:28:41 +00:00
block - > mask [ ch ] ) ;
2007-03-22 05:34:26 +00:00
}
}
}
}
2010-12-14 14:51:26 +00:00
2011-11-02 14:38:10 +00:00
/*
2010-12-15 21:12:28 +00:00
* Ensure that bap for each block and channel point to the current bap_buffer .
* They may have been switched during the bit allocation search .
*/
static void reset_block_bap ( AC3EncodeContext * s )
{
int blk , ch ;
2011-05-26 19:57:21 +00:00
uint8_t * ref_bap ;
if ( s - > ref_bap [ 0 ] [ 0 ] = = s - > bap_buffer & & s - > ref_bap_set )
2010-12-15 21:12:28 +00:00
return ;
2011-05-26 19:57:21 +00:00
ref_bap = s - > bap_buffer ;
for ( ch = 0 ; ch < = s - > channels ; ch + + ) {
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + )
2011-05-26 19:57:21 +00:00
s - > ref_bap [ ch ] [ blk ] = ref_bap + AC3_MAX_COEFS * s - > exp_ref_block [ ch ] [ blk ] ;
2011-07-14 17:02:45 +00:00
ref_bap + = AC3_MAX_COEFS * s - > num_blocks ;
2010-12-15 21:12:28 +00:00
}
2011-05-26 19:57:21 +00:00
s - > ref_bap_set = 1 ;
2010-12-15 21:12:28 +00:00
}
2011-05-26 19:53:25 +00:00
/**
* Initialize mantissa counts .
* These are set so that they are padded to the next whole group size when bits
* are counted in compute_mantissa_size .
2011-11-02 14:38:10 +00:00
*
* @ param [ in , out ] mant_cnt running counts for each bap value for each block
2011-05-26 19:53:25 +00:00
*/
static void count_mantissa_bits_init ( uint16_t mant_cnt [ AC3_MAX_BLOCKS ] [ 16 ] )
2001-07-22 14:18:56 +00:00
{
2011-05-26 19:53:25 +00:00
int blk ;
2010-12-15 21:12:28 +00:00
for ( blk = 0 ; blk < AC3_MAX_BLOCKS ; blk + + ) {
2011-05-26 19:53:25 +00:00
memset ( mant_cnt [ blk ] , 0 , sizeof ( mant_cnt [ blk ] ) ) ;
mant_cnt [ blk ] [ 1 ] = mant_cnt [ blk ] [ 2 ] = 2 ;
mant_cnt [ blk ] [ 4 ] = 1 ;
}
}
/**
* Update mantissa bit counts for all blocks in 1 channel in a given bandwidth
* range .
2011-11-02 14:38:10 +00:00
*
* @ param s AC - 3 encoder private context
* @ param ch channel index
* @ param [ in , out ] mant_cnt running counts for each bap value for each block
* @ param start starting coefficient bin
* @ param end ending coefficient bin
2011-05-26 19:53:25 +00:00
*/
static void count_mantissa_bits_update_ch ( AC3EncodeContext * s , int ch ,
uint16_t mant_cnt [ AC3_MAX_BLOCKS ] [ 16 ] ,
int start , int end )
{
int blk ;
2007-03-22 05:38:00 +00:00
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2011-04-15 23:55:09 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
2011-05-26 19:53:25 +00:00
if ( ch = = CPL_CH & & ! block - > cpl_in_use )
continue ;
s - > ac3dsp . update_bap_counts ( mant_cnt [ blk ] ,
s - > ref_bap [ ch ] [ blk ] + start ,
FFMIN ( end , block - > end_freq [ ch ] ) - start ) ;
2010-12-15 21:12:28 +00:00
}
}
2011-11-02 14:38:10 +00:00
/*
2011-05-26 19:53:25 +00:00
* Count the number of mantissa bits in the frame based on the bap values .
*/
static int count_mantissa_bits ( AC3EncodeContext * s )
{
int ch , max_end_freq ;
2011-05-28 19:27:09 +00:00
LOCAL_ALIGNED_16 ( uint16_t , mant_cnt , [ AC3_MAX_BLOCKS ] , [ 16 ] ) ;
2011-05-26 19:53:25 +00:00
count_mantissa_bits_init ( mant_cnt ) ;
max_end_freq = s - > bandwidth_code * 3 + 73 ;
for ( ch = ! s - > cpl_enabled ; ch < = s - > channels ; ch + + )
count_mantissa_bits_update_ch ( s , ch , mant_cnt , s - > start_freq [ ch ] ,
max_end_freq ) ;
return s - > ac3dsp . compute_mantissa_size ( mant_cnt ) ;
2011-05-26 16:31:31 +00:00
}
2011-05-23 15:45:51 +00:00
2011-05-26 16:31:31 +00:00
2010-12-14 14:51:30 +00:00
/**
* Run the bit allocation with a given SNR offset .
* This calculates the bit allocation pointers that will be used to determine
* the quantization of each mantissa .
2011-11-02 14:38:10 +00:00
*
* @ param s AC - 3 encoder private context
* @ param snr_offset SNR offset , 0 to 1023
2010-12-14 22:45:19 +00:00
* @ return the number of bits needed for mantissas if the given SNR offset is
* is used .
2010-12-14 14:51:30 +00:00
*/
2010-12-30 22:13:34 +00:00
static int bit_alloc ( AC3EncodeContext * s , int snr_offset )
2001-07-22 14:18:56 +00:00
{
2010-12-14 14:52:00 +00:00
int blk , ch ;
2007-03-22 05:38:00 +00:00
2019-09-19 22:17:06 +00:00
snr_offset = ( snr_offset - 240 ) * 4 ;
2001-07-22 14:18:56 +00:00
2010-12-15 21:12:28 +00:00
reset_block_bap ( s ) ;
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2011-04-15 23:55:09 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
2011-05-23 15:45:51 +00:00
2011-05-26 16:31:31 +00:00
for ( ch = ! block - > cpl_in_use ; ch < = s - > channels ; ch + + ) {
2010-12-16 22:47:07 +00:00
/* Currently the only bit allocation parameters which vary across
blocks within a frame are the exponent values . We can take
advantage of that by reusing the bit allocation pointers
whenever we reuse exponents . */
2011-03-28 18:01:27 +00:00
if ( s - > exp_strategy [ ch ] [ blk ] ! = EXP_REUSE ) {
2011-05-26 19:57:21 +00:00
s - > ac3dsp . bit_alloc_calc_bap ( block - > mask [ ch ] , block - > psd [ ch ] ,
2011-05-23 15:45:51 +00:00
s - > start_freq [ ch ] , block - > end_freq [ ch ] ,
snr_offset , s - > bit_alloc . floor ,
2011-05-26 19:57:21 +00:00
ff_ac3_bap_tab , s - > ref_bap [ ch ] [ blk ] ) ;
2010-12-16 22:47:07 +00:00
}
2001-07-22 14:18:56 +00:00
}
}
2011-05-26 16:31:31 +00:00
return count_mantissa_bits ( s ) ;
2001-07-22 14:18:56 +00:00
}
2010-12-14 14:51:26 +00:00
2011-11-02 14:38:10 +00:00
/*
2010-12-15 17:28:38 +00:00
* Constant bitrate bit allocation search .
* Find the largest SNR offset that will allow data to fit in the frame .
2010-12-14 14:51:30 +00:00
*/
2010-12-15 17:28:38 +00:00
static int cbr_bit_allocation ( AC3EncodeContext * s )
2001-07-22 14:18:56 +00:00
{
2010-12-14 14:53:40 +00:00
int ch ;
2010-12-14 22:45:19 +00:00
int bits_left ;
2010-12-17 15:02:12 +00:00
int snr_offset , snr_incr ;
2001-07-22 14:18:56 +00:00
2010-12-14 22:45:19 +00:00
bits_left = 8 * s - > frame_size - ( s - > frame_bits + s - > exponent_bits ) ;
2011-04-15 23:56:42 +00:00
if ( bits_left < 0 )
return AVERROR ( EINVAL ) ;
2010-12-14 22:45:28 +00:00
2010-12-14 22:45:22 +00:00
snr_offset = s - > coarse_snr_offset < < 4 ;
2010-12-14 22:45:28 +00:00
2010-12-31 23:22:08 +00:00
/* if previous frame SNR offset was 1023, check if current frame can also
use SNR offset of 1023. if so , skip the search . */
2011-05-23 15:45:51 +00:00
if ( ( snr_offset | s - > fine_snr_offset [ 1 ] ) = = 1023 ) {
2010-12-31 23:22:08 +00:00
if ( bit_alloc ( s , 1023 ) < = bits_left )
return 0 ;
}
2010-12-14 22:45:22 +00:00
while ( snr_offset > = 0 & &
2010-12-15 21:12:28 +00:00
bit_alloc ( s , snr_offset ) > bits_left ) {
2010-12-14 22:45:22 +00:00
snr_offset - = 64 ;
2010-12-14 22:45:28 +00:00
}
2010-12-15 17:28:44 +00:00
if ( snr_offset < 0 )
2010-12-14 14:53:30 +00:00
return AVERROR ( EINVAL ) ;
2010-12-14 22:45:28 +00:00
2010-12-15 21:12:28 +00:00
FFSWAP ( uint8_t * , s - > bap_buffer , s - > bap1_buffer ) ;
2010-12-17 15:02:12 +00:00
for ( snr_incr = 64 ; snr_incr > 0 ; snr_incr > > = 2 ) {
2010-12-31 22:59:19 +00:00
while ( snr_offset + snr_incr < = 1023 & &
2010-12-17 15:02:15 +00:00
bit_alloc ( s , snr_offset + snr_incr ) < = bits_left ) {
snr_offset + = snr_incr ;
FFSWAP ( uint8_t * , s - > bap_buffer , s - > bap1_buffer ) ;
}
2001-07-22 14:18:56 +00:00
}
2010-12-15 21:12:28 +00:00
FFSWAP ( uint8_t * , s - > bap_buffer , s - > bap1_buffer ) ;
reset_block_bap ( s ) ;
2005-12-17 18:14:38 +00:00
2010-12-14 22:45:22 +00:00
s - > coarse_snr_offset = snr_offset > > 4 ;
2011-05-23 15:45:51 +00:00
for ( ch = ! s - > cpl_on ; ch < = s - > channels ; ch + + )
2010-12-14 22:45:22 +00:00
s - > fine_snr_offset [ ch ] = snr_offset & 0xF ;
2010-12-14 14:50:45 +00:00
2001-07-22 14:18:56 +00:00
return 0 ;
}
2010-12-14 14:51:26 +00:00
2011-11-02 14:38:10 +00:00
/*
2010-12-15 17:28:38 +00:00
* Perform bit allocation search .
* Finds the SNR offset value that maximizes quality and fits in the specified
* frame size . Output is the SNR offset and a set of bit allocation pointers
* used to quantize the mantissas .
*/
2022-05-23 03:23:35 +00:00
static int ac3_compute_bit_allocation ( AC3EncodeContext * s )
2010-12-15 17:28:38 +00:00
{
count_frame_bits ( s ) ;
2011-08-05 20:00:18 +00:00
s - > exponent_bits = count_exponent_bits ( s ) ;
2010-12-15 17:28:38 +00:00
bit_alloc_masking ( s ) ;
2011-06-21 16:59:11 +00:00
return cbr_bit_allocation ( s ) ;
2010-12-15 17:28:38 +00:00
}
2010-12-14 14:51:30 +00:00
/**
* Symmetric quantization on ' levels ' levels .
2011-11-02 14:38:10 +00:00
*
* @ param c unquantized coefficient
* @ param e exponent
* @ param levels number of quantization levels
* @ return quantized coefficient
2010-12-14 14:51:30 +00:00
*/
2001-07-22 14:18:56 +00:00
static inline int sym_quant ( int c , int e , int levels )
{
2011-03-31 00:28:08 +00:00
int v = ( ( ( levels * c ) > > ( 24 - e ) ) + levels ) > > 1 ;
2011-03-04 17:11:03 +00:00
av_assert2 ( v > = 0 & & v < levels ) ;
2001-07-22 14:18:56 +00:00
return v ;
}
2010-12-14 14:51:26 +00:00
2010-12-14 14:51:30 +00:00
/**
* Asymmetric quantization on 2 ^ qbits levels .
2011-11-02 14:38:10 +00:00
*
* @ param c unquantized coefficient
* @ param e exponent
* @ param qbits number of quantization bits
* @ return quantized coefficient
2010-12-14 14:51:30 +00:00
*/
2001-07-22 14:18:56 +00:00
static inline int asym_quant ( int c , int e , int qbits )
{
2011-06-21 20:49:16 +00:00
int m ;
2011-06-21 20:14:19 +00:00
2015-10-09 19:59:04 +00:00
c = ( ( ( c * ( 1 < < e ) ) > > ( 24 - qbits ) ) + 1 ) > > 1 ;
2001-07-22 14:18:56 +00:00
m = ( 1 < < ( qbits - 1 ) ) ;
2011-06-21 20:49:16 +00:00
if ( c > = m )
c = m - 1 ;
av_assert2 ( c > = - m ) ;
return c ;
2001-07-22 14:18:56 +00:00
}
2010-12-14 14:51:26 +00:00
2010-12-14 14:53:23 +00:00
/**
* Quantize a set of mantissas for a single channel in a single block .
2011-11-02 14:38:10 +00:00
*
* @ param s Mantissa count context
* @ param fixed_coef unquantized fixed - point coefficients
* @ param exp exponents
* @ param bap bit allocation pointer indices
* @ param [ out ] qmant quantized coefficients
* @ param start_freq starting coefficient bin
* @ param end_freq ending coefficient bin
2010-12-14 14:53:23 +00:00
*/
2011-03-13 16:22:07 +00:00
static void quantize_mantissas_blk_ch ( AC3Mant * s , int32_t * fixed_coef ,
2011-05-23 15:45:51 +00:00
uint8_t * exp , uint8_t * bap ,
2011-06-21 17:39:02 +00:00
int16_t * qmant , int start_freq ,
2011-05-23 15:45:51 +00:00
int end_freq )
2010-12-14 14:53:23 +00:00
{
int i ;
2011-05-23 15:45:51 +00:00
for ( i = start_freq ; i < end_freq ; i + + ) {
2011-01-05 20:35:36 +00:00
int c = fixed_coef [ i ] ;
2011-03-11 18:03:26 +00:00
int e = exp [ i ] ;
2011-03-27 14:47:10 +00:00
int v = bap [ i ] ;
switch ( v ) {
2024-04-25 09:18:18 +00:00
case 0 :
break ;
2010-12-14 14:53:23 +00:00
case 1 :
v = sym_quant ( c , e , 3 ) ;
switch ( s - > mant1_cnt ) {
case 0 :
s - > qmant1_ptr = & qmant [ i ] ;
v = 9 * v ;
s - > mant1_cnt = 1 ;
break ;
case 1 :
* s - > qmant1_ptr + = 3 * v ;
s - > mant1_cnt = 2 ;
v = 128 ;
break ;
default :
* s - > qmant1_ptr + = v ;
s - > mant1_cnt = 0 ;
v = 128 ;
break ;
}
break ;
case 2 :
v = sym_quant ( c , e , 5 ) ;
switch ( s - > mant2_cnt ) {
case 0 :
s - > qmant2_ptr = & qmant [ i ] ;
v = 25 * v ;
s - > mant2_cnt = 1 ;
break ;
case 1 :
* s - > qmant2_ptr + = 5 * v ;
s - > mant2_cnt = 2 ;
v = 128 ;
break ;
default :
* s - > qmant2_ptr + = v ;
s - > mant2_cnt = 0 ;
v = 128 ;
break ;
}
break ;
case 3 :
v = sym_quant ( c , e , 7 ) ;
break ;
case 4 :
v = sym_quant ( c , e , 11 ) ;
switch ( s - > mant4_cnt ) {
case 0 :
s - > qmant4_ptr = & qmant [ i ] ;
v = 11 * v ;
s - > mant4_cnt = 1 ;
break ;
default :
* s - > qmant4_ptr + = v ;
s - > mant4_cnt = 0 ;
v = 128 ;
break ;
}
break ;
case 5 :
v = sym_quant ( c , e , 15 ) ;
break ;
case 14 :
v = asym_quant ( c , e , 14 ) ;
break ;
case 15 :
v = asym_quant ( c , e , 16 ) ;
break ;
default :
2011-03-27 14:47:10 +00:00
v = asym_quant ( c , e , v - 1 ) ;
2010-12-14 14:53:23 +00:00
break ;
}
qmant [ i ] = v ;
}
}
/**
* Quantize mantissas using coefficients , exponents , and bit allocation pointers .
2011-11-02 14:38:10 +00:00
*
* @ param s AC - 3 encoder private context
2010-12-14 14:53:23 +00:00
*/
2022-05-23 03:23:35 +00:00
static void ac3_quantize_mantissas ( AC3EncodeContext * s )
2010-12-14 14:53:23 +00:00
{
2011-05-23 15:45:51 +00:00
int blk , ch , ch0 = 0 , got_cpl ;
2010-12-14 14:53:23 +00:00
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2010-12-15 17:28:41 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
2011-03-13 16:22:07 +00:00
AC3Mant m = { 0 } ;
2010-12-14 14:53:23 +00:00
2011-05-23 15:45:51 +00:00
got_cpl = ! block - > cpl_in_use ;
for ( ch = 1 ; ch < = s - > channels ; ch + + ) {
if ( ! got_cpl & & ch > 1 & & block - > channel_in_cpl [ ch - 1 ] ) {
ch0 = ch - 1 ;
ch = CPL_CH ;
got_cpl = 1 ;
}
2011-03-13 16:22:07 +00:00
quantize_mantissas_blk_ch ( & m , block - > fixed_coef [ ch ] ,
2011-05-26 19:57:21 +00:00
s - > blocks [ s - > exp_ref_block [ ch ] [ blk ] ] . exp [ ch ] ,
s - > ref_bap [ ch ] [ blk ] , block - > qmant [ ch ] ,
2011-05-23 15:45:51 +00:00
s - > start_freq [ ch ] , block - > end_freq [ ch ] ) ;
if ( ch = = CPL_CH )
ch = ch0 ;
2010-12-14 14:53:23 +00:00
}
}
}
2011-11-02 14:38:10 +00:00
/*
2010-12-14 14:53:20 +00:00
* Write the AC - 3 frame header to the output bitstream .
*/
2011-05-24 19:20:56 +00:00
static void ac3_output_frame_header ( AC3EncodeContext * s )
2010-12-14 14:53:20 +00:00
{
2011-03-25 21:12:26 +00:00
AC3EncOptions * opt = & s - > options ;
2010-12-14 14:53:20 +00:00
put_bits ( & s - > pb , 16 , 0x0b77 ) ; /* frame header */
put_bits ( & s - > pb , 16 , 0 ) ; /* crc1: will be filled later */
put_bits ( & s - > pb , 2 , s - > bit_alloc . sr_code ) ;
put_bits ( & s - > pb , 6 , s - > frame_size_code + ( s - > frame_size - s - > frame_size_min ) / 2 ) ;
put_bits ( & s - > pb , 5 , s - > bitstream_id ) ;
put_bits ( & s - > pb , 3 , s - > bitstream_mode ) ;
put_bits ( & s - > pb , 3 , s - > channel_mode ) ;
if ( ( s - > channel_mode & 0x01 ) & & s - > channel_mode ! = AC3_CHMODE_MONO )
2011-03-25 21:12:26 +00:00
put_bits ( & s - > pb , 2 , s - > center_mix_level ) ;
2010-12-14 14:53:20 +00:00
if ( s - > channel_mode & 0x04 )
2011-03-25 21:12:26 +00:00
put_bits ( & s - > pb , 2 , s - > surround_mix_level ) ;
2010-12-14 14:53:20 +00:00
if ( s - > channel_mode = = AC3_CHMODE_STEREO )
2011-03-25 21:12:26 +00:00
put_bits ( & s - > pb , 2 , opt - > dolby_surround_mode ) ;
2010-12-14 14:53:20 +00:00
put_bits ( & s - > pb , 1 , s - > lfe_on ) ; /* LFE */
2011-03-25 21:12:26 +00:00
put_bits ( & s - > pb , 5 , - opt - > dialogue_level ) ;
2010-12-14 14:53:20 +00:00
put_bits ( & s - > pb , 1 , 0 ) ; /* no compression control word */
put_bits ( & s - > pb , 1 , 0 ) ; /* no lang code */
2011-03-25 21:12:26 +00:00
put_bits ( & s - > pb , 1 , opt - > audio_production_info ) ;
if ( opt - > audio_production_info ) {
put_bits ( & s - > pb , 5 , opt - > mixing_level - 80 ) ;
put_bits ( & s - > pb , 2 , opt - > room_type ) ;
}
put_bits ( & s - > pb , 1 , opt - > copyright ) ;
put_bits ( & s - > pb , 1 , opt - > original ) ;
if ( s - > bitstream_id = = 6 ) {
/* alternate bit stream syntax */
put_bits ( & s - > pb , 1 , opt - > extended_bsi_1 ) ;
if ( opt - > extended_bsi_1 ) {
put_bits ( & s - > pb , 2 , opt - > preferred_stereo_downmix ) ;
put_bits ( & s - > pb , 3 , s - > ltrt_center_mix_level ) ;
put_bits ( & s - > pb , 3 , s - > ltrt_surround_mix_level ) ;
put_bits ( & s - > pb , 3 , s - > loro_center_mix_level ) ;
put_bits ( & s - > pb , 3 , s - > loro_surround_mix_level ) ;
}
put_bits ( & s - > pb , 1 , opt - > extended_bsi_2 ) ;
if ( opt - > extended_bsi_2 ) {
put_bits ( & s - > pb , 2 , opt - > dolby_surround_ex_mode ) ;
put_bits ( & s - > pb , 2 , opt - > dolby_headphone_mode ) ;
put_bits ( & s - > pb , 1 , opt - > ad_converter_type ) ;
put_bits ( & s - > pb , 9 , 0 ) ; /* xbsi2 and encinfo : reserved */
}
} else {
2024-04-25 09:18:18 +00:00
put_bits ( & s - > pb , 1 , 0 ) ; /* no time code 1 */
put_bits ( & s - > pb , 1 , 0 ) ; /* no time code 2 */
2011-03-25 21:12:26 +00:00
}
2010-12-14 14:53:20 +00:00
put_bits ( & s - > pb , 1 , 0 ) ; /* no additional bit stream info */
}
2011-11-02 14:38:10 +00:00
/*
2010-12-14 14:51:30 +00:00
* Write one audio block to the output bitstream .
*/
2011-01-15 01:58:55 +00:00
static void output_audio_block ( AC3EncodeContext * s , int blk )
2001-07-22 14:18:56 +00:00
{
2014-05-07 14:52:36 +00:00
int ch , i , baie , bnd , got_cpl , av_uninit ( ch0 ) ;
2011-01-15 01:58:55 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
2001-07-22 14:18:56 +00:00
2010-12-15 17:28:44 +00:00
/* block switching */
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 ) {
2011-05-24 23:38:30 +00:00
for ( ch = 0 ; ch < s - > fbw_channels ; ch + + )
put_bits ( & s - > pb , 1 , 0 ) ;
2011-05-24 19:20:56 +00:00
}
2010-12-15 17:28:44 +00:00
/* dither flags */
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 ) {
2011-05-24 23:38:30 +00:00
for ( ch = 0 ; ch < s - > fbw_channels ; ch + + )
put_bits ( & s - > pb , 1 , 1 ) ;
2011-05-24 19:20:56 +00:00
}
2010-12-15 17:28:44 +00:00
/* dynamic range codes */
put_bits ( & s - > pb , 1 , 0 ) ;
2011-05-24 19:20:56 +00:00
/* spectral extension */
if ( s - > eac3 )
put_bits ( & s - > pb , 1 , 0 ) ;
2010-12-15 17:28:44 +00:00
/* channel coupling */
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 )
2011-05-24 23:38:30 +00:00
put_bits ( & s - > pb , 1 , block - > new_cpl_strategy ) ;
2011-05-23 15:45:51 +00:00
if ( block - > new_cpl_strategy ) {
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 )
2011-05-24 23:38:30 +00:00
put_bits ( & s - > pb , 1 , block - > cpl_in_use ) ;
2011-05-23 15:45:51 +00:00
if ( block - > cpl_in_use ) {
int start_sub , end_sub ;
2011-05-24 19:20:56 +00:00
if ( s - > eac3 )
put_bits ( & s - > pb , 1 , 0 ) ; /* enhanced coupling */
if ( ! s - > eac3 | | s - > channel_mode ! = AC3_CHMODE_STEREO ) {
2011-05-24 23:38:30 +00:00
for ( ch = 1 ; ch < = s - > fbw_channels ; ch + + )
put_bits ( & s - > pb , 1 , block - > channel_in_cpl [ ch ] ) ;
2011-05-24 19:20:56 +00:00
}
2011-05-23 15:45:51 +00:00
if ( s - > channel_mode = = AC3_CHMODE_STEREO )
put_bits ( & s - > pb , 1 , 0 ) ; /* phase flags in use */
start_sub = ( s - > start_freq [ CPL_CH ] - 37 ) / 12 ;
end_sub = ( s - > cpl_end_freq - 37 ) / 12 ;
put_bits ( & s - > pb , 4 , start_sub ) ;
put_bits ( & s - > pb , 4 , end_sub - 3 ) ;
2011-05-24 19:20:56 +00:00
/* coupling band structure */
if ( s - > eac3 ) {
put_bits ( & s - > pb , 1 , 0 ) ; /* use default */
} else {
2011-05-24 23:38:30 +00:00
for ( bnd = start_sub + 1 ; bnd < end_sub ; bnd + + )
put_bits ( & s - > pb , 1 , ff_eac3_default_cpl_band_struct [ bnd ] ) ;
2011-05-24 19:20:56 +00:00
}
2011-05-23 15:45:51 +00:00
}
}
/* coupling coordinates */
if ( block - > cpl_in_use ) {
for ( ch = 1 ; ch < = s - > fbw_channels ; ch + + ) {
if ( block - > channel_in_cpl [ ch ] ) {
2011-08-05 20:28:39 +00:00
if ( ! s - > eac3 | | block - > new_cpl_coords [ ch ] ! = 2 )
put_bits ( & s - > pb , 1 , block - > new_cpl_coords [ ch ] ) ;
if ( block - > new_cpl_coords [ ch ] ) {
2011-05-23 15:45:51 +00:00
put_bits ( & s - > pb , 2 , block - > cpl_master_exp [ ch ] ) ;
for ( bnd = 0 ; bnd < s - > num_cpl_bands ; bnd + + ) {
put_bits ( & s - > pb , 4 , block - > cpl_coord_exp [ ch ] [ bnd ] ) ;
put_bits ( & s - > pb , 4 , block - > cpl_coord_mant [ ch ] [ bnd ] ) ;
}
}
}
}
2001-07-22 14:18:56 +00:00
}
2010-12-15 17:28:44 +00:00
/* stereo rematrixing */
2010-12-14 14:51:09 +00:00
if ( s - > channel_mode = = AC3_CHMODE_STEREO ) {
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 | | blk > 0 )
2011-05-24 23:38:30 +00:00
put_bits ( & s - > pb , 1 , block - > new_rematrixing_strategy ) ;
2011-01-08 23:21:17 +00:00
if ( block - > new_rematrixing_strategy ) {
/* rematrixing flags */
2011-05-23 15:45:51 +00:00
for ( bnd = 0 ; bnd < block - > num_rematrixing_bands ; bnd + + )
put_bits ( & s - > pb , 1 , block - > rematrixing_flags [ bnd ] ) ;
2010-12-14 14:51:09 +00:00
}
}
2001-07-22 14:18:56 +00:00
/* exponent strategy */
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 ) {
2011-05-24 23:38:30 +00:00
for ( ch = ! block - > cpl_in_use ; ch < = s - > fbw_channels ; ch + + )
put_bits ( & s - > pb , 2 , s - > exp_strategy [ ch ] [ blk ] ) ;
if ( s - > lfe_on )
put_bits ( & s - > pb , 1 , s - > exp_strategy [ s - > lfe_channel ] [ blk ] ) ;
2011-05-24 19:20:56 +00:00
}
2002-04-08 12:08:03 +00:00
2010-12-14 14:51:09 +00:00
/* bandwidth */
2011-05-23 15:45:51 +00:00
for ( ch = 1 ; ch < = s - > fbw_channels ; ch + + ) {
if ( s - > exp_strategy [ ch ] [ blk ] ! = EXP_REUSE & & ! block - > channel_in_cpl [ ch ] )
2011-04-16 02:49:05 +00:00
put_bits ( & s - > pb , 6 , s - > bandwidth_code ) ;
2001-07-22 14:18:56 +00:00
}
2005-12-17 18:14:38 +00:00
2001-07-22 14:18:56 +00:00
/* exponents */
2011-05-23 15:45:51 +00:00
for ( ch = ! block - > cpl_in_use ; ch < = s - > channels ; ch + + ) {
2010-12-16 21:09:22 +00:00
int nb_groups ;
2011-05-23 15:45:51 +00:00
int cpl = ( ch = = CPL_CH ) ;
2010-12-16 21:09:22 +00:00
2011-01-15 01:58:55 +00:00
if ( s - > exp_strategy [ ch ] [ blk ] = = EXP_REUSE )
2001-07-22 14:18:56 +00:00
continue ;
2010-12-15 17:28:44 +00:00
/* DC exponent */
2011-05-23 15:45:51 +00:00
put_bits ( & s - > pb , 4 , block - > grouped_exp [ ch ] [ 0 ] > > cpl ) ;
2010-12-14 14:53:26 +00:00
2010-12-15 17:28:44 +00:00
/* exponent groups */
2011-05-23 15:45:51 +00:00
nb_groups = exponent_group_tab [ cpl ] [ s - > exp_strategy [ ch ] [ blk ] - 1 ] [ block - > end_freq [ ch ] - s - > start_freq [ ch ] ] ;
2010-12-16 21:09:22 +00:00
for ( i = 1 ; i < = nb_groups ; i + + )
2010-12-15 17:28:41 +00:00
put_bits ( & s - > pb , 7 , block - > grouped_exp [ ch ] [ i ] ) ;
2001-07-22 14:18:56 +00:00
2010-12-15 17:28:44 +00:00
/* gain range info */
2011-05-23 15:45:51 +00:00
if ( ch ! = s - > lfe_channel & & ! cpl )
2010-12-15 17:28:44 +00:00
put_bits ( & s - > pb , 2 , 0 ) ;
2001-07-22 14:18:56 +00:00
}
/* bit allocation info */
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 ) {
2011-05-24 23:38:30 +00:00
baie = ( blk = = 0 ) ;
put_bits ( & s - > pb , 1 , baie ) ;
if ( baie ) {
put_bits ( & s - > pb , 2 , s - > slow_decay_code ) ;
put_bits ( & s - > pb , 2 , s - > fast_decay_code ) ;
put_bits ( & s - > pb , 2 , s - > slow_gain_code ) ;
put_bits ( & s - > pb , 2 , s - > db_per_bit_code ) ;
put_bits ( & s - > pb , 3 , s - > floor_code ) ;
}
2001-07-22 14:18:56 +00:00
}
/* snr offset */
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 ) {
2011-05-24 23:38:30 +00:00
put_bits ( & s - > pb , 1 , block - > new_snr_offsets ) ;
if ( block - > new_snr_offsets ) {
put_bits ( & s - > pb , 6 , s - > coarse_snr_offset ) ;
for ( ch = ! block - > cpl_in_use ; ch < = s - > channels ; ch + + ) {
put_bits ( & s - > pb , 4 , s - > fine_snr_offset [ ch ] ) ;
put_bits ( & s - > pb , 3 , s - > fast_gain_code [ ch ] ) ;
}
2001-07-22 14:18:56 +00:00
}
2011-05-24 19:20:56 +00:00
} else {
put_bits ( & s - > pb , 1 , 0 ) ; /* no converter snr offset */
2001-07-22 14:18:56 +00:00
}
2005-12-17 18:14:38 +00:00
2011-05-23 15:45:51 +00:00
/* coupling leak */
if ( block - > cpl_in_use ) {
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 | | block - > new_cpl_leak ! = 2 )
2011-05-24 23:38:30 +00:00
put_bits ( & s - > pb , 1 , block - > new_cpl_leak ) ;
2011-05-23 15:45:51 +00:00
if ( block - > new_cpl_leak ) {
put_bits ( & s - > pb , 3 , s - > bit_alloc . cpl_fast_leak ) ;
put_bits ( & s - > pb , 3 , s - > bit_alloc . cpl_slow_leak ) ;
}
}
2011-05-24 19:20:56 +00:00
if ( ! s - > eac3 ) {
2011-05-24 23:38:30 +00:00
put_bits ( & s - > pb , 1 , 0 ) ; /* no delta bit allocation */
put_bits ( & s - > pb , 1 , 0 ) ; /* no data to skip */
2011-05-24 19:20:56 +00:00
}
2001-07-22 14:18:56 +00:00
2010-12-15 17:28:44 +00:00
/* mantissas */
2011-05-23 15:45:51 +00:00
got_cpl = ! block - > cpl_in_use ;
for ( ch = 1 ; ch < = s - > channels ; ch + + ) {
2001-07-22 14:18:56 +00:00
int b , q ;
2011-05-23 15:45:51 +00:00
if ( ! got_cpl & & ch > 1 & & block - > channel_in_cpl [ ch - 1 ] ) {
ch0 = ch - 1 ;
ch = CPL_CH ;
got_cpl = 1 ;
}
for ( i = s - > start_freq [ ch ] ; i < block - > end_freq [ ch ] ; i + + ) {
2010-12-15 17:28:41 +00:00
q = block - > qmant [ ch ] [ i ] ;
2011-05-26 19:57:21 +00:00
b = s - > ref_bap [ ch ] [ blk ] [ i ] ;
2010-12-14 14:51:09 +00:00
switch ( b ) {
2011-06-21 17:39:02 +00:00
case 0 : break ;
case 1 : if ( q ! = 128 ) put_bits ( & s - > pb , 5 , q ) ; break ;
case 2 : if ( q ! = 128 ) put_bits ( & s - > pb , 7 , q ) ; break ;
case 3 : put_sbits ( & s - > pb , 3 , q ) ; break ;
case 4 : if ( q ! = 128 ) put_bits ( & s - > pb , 7 , q ) ; break ;
case 14 : put_sbits ( & s - > pb , 14 , q ) ; break ;
case 15 : put_sbits ( & s - > pb , 16 , q ) ; break ;
default : put_sbits ( & s - > pb , b - 1 , q ) ; break ;
2001-07-22 14:18:56 +00:00
}
}
2011-05-23 15:45:51 +00:00
if ( ch = = CPL_CH )
ch = ch0 ;
2001-07-22 14:18:56 +00:00
}
}
2010-12-14 14:51:26 +00:00
2010-12-14 14:51:30 +00:00
/** CRC-16 Polynomial */
2001-07-22 14:18:56 +00:00
# define CRC16_POLY ((1 << 0) | (1 << 2) | (1 << 15) | (1 << 16))
2010-12-14 14:51:26 +00:00
2001-07-22 14:18:56 +00:00
static unsigned int mul_poly ( unsigned int a , unsigned int b , unsigned int poly )
{
unsigned int c ;
c = 0 ;
while ( a ) {
if ( a & 1 )
c ^ = b ;
a = a > > 1 ;
b = b < < 1 ;
if ( b & ( 1 < < 16 ) )
b ^ = poly ;
}
return c ;
}
2010-12-14 14:51:26 +00:00
2001-07-22 14:18:56 +00:00
static unsigned int pow_poly ( unsigned int a , unsigned int n , unsigned int poly )
{
unsigned int r ;
r = 1 ;
while ( n ) {
if ( n & 1 )
r = mul_poly ( r , a , poly ) ;
a = mul_poly ( a , a , poly ) ;
n > > = 1 ;
}
return r ;
}
2010-12-14 14:51:26 +00:00
2011-11-02 14:38:10 +00:00
/*
2010-12-14 14:51:30 +00:00
* Fill the end of the frame with 0 ' s and compute the two CRCs .
*/
2010-12-14 14:52:08 +00:00
static void output_frame_end ( AC3EncodeContext * s )
2001-07-22 14:18:56 +00:00
{
2010-12-23 18:01:23 +00:00
const AVCRC * crc_ctx = av_crc_get_table ( AV_CRC_16_ANSI ) ;
2010-12-23 18:01:26 +00:00
int frame_size_58 , pad_bytes , crc1 , crc2_partial , crc2 , crc_inv ;
2003-02-11 16:35:48 +00:00
uint8_t * frame ;
2001-07-22 14:18:56 +00:00
2010-12-23 18:01:19 +00:00
frame_size_58 = ( ( s - > frame_size > > 2 ) + ( s - > frame_size > > 4 ) ) < < 1 ;
2010-12-15 17:28:44 +00:00
/* pad the remainder of the frame with zeros */
2011-03-04 17:12:01 +00:00
av_assert2 ( s - > frame_size * 8 - put_bits_count ( & s - > pb ) > = 18 ) ;
2001-07-22 14:18:56 +00:00
flush_put_bits ( & s - > pb ) ;
frame = s - > pb . buf ;
2010-12-14 14:52:14 +00:00
pad_bytes = s - > frame_size - ( put_bits_ptr ( & s - > pb ) - frame ) - 2 ;
2011-03-04 17:11:03 +00:00
av_assert2 ( pad_bytes > = 0 ) ;
2010-12-14 14:52:12 +00:00
if ( pad_bytes > 0 )
memset ( put_bits_ptr ( & s - > pb ) , 0 , pad_bytes ) ;
2005-12-17 18:14:38 +00:00
2011-05-24 19:20:56 +00:00
if ( s - > eac3 ) {
/* compute crc2 */
crc2_partial = av_crc ( crc_ctx , 0 , frame + 2 , s - > frame_size - 5 ) ;
} else {
2024-04-25 09:18:18 +00:00
/* compute crc1 */
/* this is not so easy because it is at the beginning of the data... */
crc1 = av_bswap16 ( av_crc ( crc_ctx , 0 , frame + 4 , frame_size_58 - 4 ) ) ;
crc_inv = s - > crc_inv [ s - > frame_size > s - > frame_size_min ] ;
crc1 = mul_poly ( crc_inv , crc1 , CRC16_POLY ) ;
AV_WB16 ( frame + 2 , crc1 ) ;
2005-12-17 18:14:38 +00:00
2024-04-25 09:18:18 +00:00
/* compute crc2 */
crc2_partial = av_crc ( crc_ctx , 0 , frame + frame_size_58 ,
s - > frame_size - frame_size_58 - 3 ) ;
2011-05-24 19:20:56 +00:00
}
2010-12-23 18:01:26 +00:00
crc2 = av_crc ( crc_ctx , crc2_partial , frame + s - > frame_size - 3 , 1 ) ;
/* ensure crc2 does not match sync word by flipping crcrsv bit if needed */
if ( crc2 = = 0x770B ) {
frame [ s - > frame_size - 3 ] ^ = 0x1 ;
crc2 = av_crc ( crc_ctx , crc2_partial , frame + s - > frame_size - 3 , 1 ) ;
}
crc2 = av_bswap16 ( crc2 ) ;
2010-12-23 18:01:19 +00:00
AV_WB16 ( frame + s - > frame_size - 2 , crc2 ) ;
2001-07-22 14:18:56 +00:00
}
2010-12-14 14:51:26 +00:00
2010-12-14 14:53:13 +00:00
/**
* Write the frame to the output bitstream .
2011-11-02 14:38:10 +00:00
*
* @ param s AC - 3 encoder private context
* @ param frame output data buffer
2010-12-14 14:53:13 +00:00
*/
2022-05-23 03:23:35 +00:00
static void ac3_output_frame ( AC3EncodeContext * s , unsigned char * frame )
2010-12-14 14:53:13 +00:00
{
int blk ;
2022-05-23 03:23:35 +00:00
init_put_bits ( & s - > pb , frame , s - > frame_size ) ;
2010-12-14 14:53:13 +00:00
2011-06-10 15:45:03 +00:00
s - > output_frame_header ( s ) ;
2010-12-14 14:53:13 +00:00
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + )
2010-12-14 22:45:31 +00:00
output_audio_block ( s , blk ) ;
2010-12-14 14:53:13 +00:00
output_frame_end ( s ) ;
}
2022-05-23 03:23:35 +00:00
int ff_ac3_encode_frame_common_end ( AVCodecContext * avctx , AVPacket * avpkt ,
const AVFrame * frame , int * got_packet_ptr )
{
AC3EncodeContext * const s = avctx - > priv_data ;
int ret ;
ac3_apply_rematrixing ( s ) ;
ac3_process_exponents ( s ) ;
ret = ac3_compute_bit_allocation ( s ) ;
if ( ret ) {
av_log ( avctx , AV_LOG_ERROR , " Bit allocation failed. Try increasing the bitrate. \n " ) ;
return ret ;
}
ac3_group_exponents ( s ) ;
ac3_quantize_mantissas ( s ) ;
2024-04-25 09:18:18 +00:00
ret = ff_get_encode_buffer ( avctx , avpkt , s - > frame_size , 0 ) ;
if ( ret < 0 )
2022-05-23 03:23:35 +00:00
return ret ;
ac3_output_frame ( s , avpkt - > data ) ;
if ( frame - > pts ! = AV_NOPTS_VALUE )
avpkt - > pts = frame - > pts - ff_samples_to_time_base ( avctx , avctx - > initial_padding ) ;
* got_packet_ptr = 1 ;
return 0 ;
}
2010-12-14 14:53:13 +00:00
2011-07-13 17:53:58 +00:00
static void dprint_options ( AC3EncodeContext * s )
2011-03-25 21:12:26 +00:00
{
# ifdef DEBUG
2011-07-13 17:53:58 +00:00
AVCodecContext * avctx = s - > avctx ;
2011-03-25 21:12:26 +00:00
AC3EncOptions * opt = & s - > options ;
char strbuf [ 32 ] ;
switch ( s - > bitstream_id ) {
2011-05-24 23:38:30 +00:00
case 6 : av_strlcpy ( strbuf , " AC-3 (alt syntax) " , 32 ) ; break ;
case 8 : av_strlcpy ( strbuf , " AC-3 (standard) " , 32 ) ; break ;
case 9 : av_strlcpy ( strbuf , " AC-3 (dnet half-rate) " , 32 ) ; break ;
case 10 : av_strlcpy ( strbuf , " AC-3 (dnet quater-rate) " , 32 ) ; break ;
case 16 : av_strlcpy ( strbuf , " E-AC-3 (enhanced) " , 32 ) ; break ;
2011-03-25 21:12:26 +00:00
default : snprintf ( strbuf , 32 , " ERROR " ) ;
}
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " bitstream_id: %s (%d) \n " , strbuf , s - > bitstream_id ) ;
ff_dlog ( avctx , " sample_fmt: %s \n " , av_get_sample_fmt_name ( avctx - > sample_fmt ) ) ;
2024-04-25 09:18:18 +00:00
av_channel_layout_describe ( & avctx - > ch_layout , strbuf , sizeof ( strbuf ) ) ;
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " channel_layout: %s \n " , strbuf ) ;
ff_dlog ( avctx , " sample_rate: %d \n " , s - > sample_rate ) ;
ff_dlog ( avctx , " bit_rate: %d \n " , s - > bit_rate ) ;
ff_dlog ( avctx , " blocks/frame: %d (code=%d) \n " , s - > num_blocks , s - > num_blks_code ) ;
2011-03-25 21:12:26 +00:00
if ( s - > cutoff )
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " cutoff: %d \n " , s - > cutoff ) ;
2011-03-25 21:12:26 +00:00
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " per_frame_metadata: %s \n " ,
2011-03-25 21:12:26 +00:00
opt - > allow_per_frame_metadata ? " on " : " off " ) ;
if ( s - > has_center )
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " center_mixlev: %0.3f (%d) \n " , opt - > center_mix_level ,
2011-03-25 21:12:26 +00:00
s - > center_mix_level ) ;
else
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " center_mixlev: {not written} \n " ) ;
2011-03-25 21:12:26 +00:00
if ( s - > has_surround )
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " surround_mixlev: %0.3f (%d) \n " , opt - > surround_mix_level ,
2011-03-25 21:12:26 +00:00
s - > surround_mix_level ) ;
else
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " surround_mixlev: {not written} \n " ) ;
2011-03-25 21:12:26 +00:00
if ( opt - > audio_production_info ) {
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " mixing_level: %ddB \n " , opt - > mixing_level ) ;
2011-03-25 21:12:26 +00:00
switch ( opt - > room_type ) {
2011-08-09 22:11:08 +00:00
case AC3ENC_OPT_NOT_INDICATED : av_strlcpy ( strbuf , " notindicated " , 32 ) ; break ;
case AC3ENC_OPT_LARGE_ROOM : av_strlcpy ( strbuf , " large " , 32 ) ; break ;
case AC3ENC_OPT_SMALL_ROOM : av_strlcpy ( strbuf , " small " , 32 ) ; break ;
2011-03-25 21:12:26 +00:00
default : snprintf ( strbuf , 32 , " ERROR (%d) " , opt - > room_type ) ;
}
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " room_type: %s \n " , strbuf ) ;
2011-03-25 21:12:26 +00:00
} else {
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " mixing_level: {not written} \n " ) ;
ff_dlog ( avctx , " room_type: {not written} \n " ) ;
2011-03-25 21:12:26 +00:00
}
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " copyright: %s \n " , opt - > copyright ? " on " : " off " ) ;
ff_dlog ( avctx , " dialnorm: %ddB \n " , opt - > dialogue_level ) ;
2011-03-25 21:12:26 +00:00
if ( s - > channel_mode = = AC3_CHMODE_STEREO ) {
switch ( opt - > dolby_surround_mode ) {
2011-08-09 22:11:08 +00:00
case AC3ENC_OPT_NOT_INDICATED : av_strlcpy ( strbuf , " notindicated " , 32 ) ; break ;
case AC3ENC_OPT_MODE_ON : av_strlcpy ( strbuf , " on " , 32 ) ; break ;
case AC3ENC_OPT_MODE_OFF : av_strlcpy ( strbuf , " off " , 32 ) ; break ;
2011-03-25 21:12:26 +00:00
default : snprintf ( strbuf , 32 , " ERROR (%d) " , opt - > dolby_surround_mode ) ;
}
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " dsur_mode: %s \n " , strbuf ) ;
2011-03-25 21:12:26 +00:00
} else {
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " dsur_mode: {not written} \n " ) ;
2011-03-25 21:12:26 +00:00
}
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " original: %s \n " , opt - > original ? " on " : " off " ) ;
2011-03-25 21:12:26 +00:00
if ( s - > bitstream_id = = 6 ) {
if ( opt - > extended_bsi_1 ) {
switch ( opt - > preferred_stereo_downmix ) {
2011-08-09 22:11:08 +00:00
case AC3ENC_OPT_NOT_INDICATED : av_strlcpy ( strbuf , " notindicated " , 32 ) ; break ;
case AC3ENC_OPT_DOWNMIX_LTRT : av_strlcpy ( strbuf , " ltrt " , 32 ) ; break ;
case AC3ENC_OPT_DOWNMIX_LORO : av_strlcpy ( strbuf , " loro " , 32 ) ; break ;
2011-03-25 21:12:26 +00:00
default : snprintf ( strbuf , 32 , " ERROR (%d) " , opt - > preferred_stereo_downmix ) ;
}
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " dmix_mode: %s \n " , strbuf ) ;
ff_dlog ( avctx , " ltrt_cmixlev: %0.3f (%d) \n " ,
2011-03-25 21:12:26 +00:00
opt - > ltrt_center_mix_level , s - > ltrt_center_mix_level ) ;
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " ltrt_surmixlev: %0.3f (%d) \n " ,
2011-03-25 21:12:26 +00:00
opt - > ltrt_surround_mix_level , s - > ltrt_surround_mix_level ) ;
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " loro_cmixlev: %0.3f (%d) \n " ,
2011-03-25 21:12:26 +00:00
opt - > loro_center_mix_level , s - > loro_center_mix_level ) ;
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " loro_surmixlev: %0.3f (%d) \n " ,
2011-03-25 21:12:26 +00:00
opt - > loro_surround_mix_level , s - > loro_surround_mix_level ) ;
} else {
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " extended bitstream info 1: {not written} \n " ) ;
2011-03-25 21:12:26 +00:00
}
if ( opt - > extended_bsi_2 ) {
switch ( opt - > dolby_surround_ex_mode ) {
2011-08-09 22:11:08 +00:00
case AC3ENC_OPT_NOT_INDICATED : av_strlcpy ( strbuf , " notindicated " , 32 ) ; break ;
case AC3ENC_OPT_MODE_ON : av_strlcpy ( strbuf , " on " , 32 ) ; break ;
case AC3ENC_OPT_MODE_OFF : av_strlcpy ( strbuf , " off " , 32 ) ; break ;
2011-03-25 21:12:26 +00:00
default : snprintf ( strbuf , 32 , " ERROR (%d) " , opt - > dolby_surround_ex_mode ) ;
}
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " dsurex_mode: %s \n " , strbuf ) ;
2011-03-25 21:12:26 +00:00
switch ( opt - > dolby_headphone_mode ) {
2011-08-09 22:11:08 +00:00
case AC3ENC_OPT_NOT_INDICATED : av_strlcpy ( strbuf , " notindicated " , 32 ) ; break ;
case AC3ENC_OPT_MODE_ON : av_strlcpy ( strbuf , " on " , 32 ) ; break ;
case AC3ENC_OPT_MODE_OFF : av_strlcpy ( strbuf , " off " , 32 ) ; break ;
2011-03-25 21:12:26 +00:00
default : snprintf ( strbuf , 32 , " ERROR (%d) " , opt - > dolby_headphone_mode ) ;
}
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " dheadphone_mode: %s \n " , strbuf ) ;
2011-03-25 21:12:26 +00:00
switch ( opt - > ad_converter_type ) {
2011-08-09 22:11:08 +00:00
case AC3ENC_OPT_ADCONV_STANDARD : av_strlcpy ( strbuf , " standard " , 32 ) ; break ;
case AC3ENC_OPT_ADCONV_HDCD : av_strlcpy ( strbuf , " hdcd " , 32 ) ; break ;
2011-03-25 21:12:26 +00:00
default : snprintf ( strbuf , 32 , " ERROR (%d) " , opt - > ad_converter_type ) ;
}
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " ad_conv_type: %s \n " , strbuf ) ;
2011-03-25 21:12:26 +00:00
} else {
2015-03-16 08:57:36 +00:00
ff_dlog ( avctx , " extended bitstream info 2: {not written} \n " ) ;
2011-03-25 21:12:26 +00:00
}
}
# endif
}
# define FLT_OPTION_THRESHOLD 0.01
static int validate_float_option ( float v , const float * v_list , int v_list_size )
{
int i ;
for ( i = 0 ; i < v_list_size ; i + + ) {
if ( v < ( v_list [ i ] + FLT_OPTION_THRESHOLD ) & &
v > ( v_list [ i ] - FLT_OPTION_THRESHOLD ) )
break ;
}
if ( i = = v_list_size )
2018-12-31 17:39:55 +00:00
return AVERROR ( EINVAL ) ;
2011-03-25 21:12:26 +00:00
return i ;
}
static void validate_mix_level ( void * log_ctx , const char * opt_name ,
float * opt_param , const float * list ,
int list_size , int default_value , int min_value ,
int * ctx_param )
{
int mixlev = validate_float_option ( * opt_param , list , list_size ) ;
if ( mixlev < min_value ) {
mixlev = default_value ;
if ( * opt_param > = 0.0 ) {
av_log ( log_ctx , AV_LOG_WARNING , " requested %s is not valid. using "
" default value: %0.3f \n " , opt_name , list [ mixlev ] ) ;
}
}
* opt_param = list [ mixlev ] ;
* ctx_param = mixlev ;
}
/**
* Validate metadata options as set by AVOption system .
* These values can optionally be changed per - frame .
2011-11-02 14:38:10 +00:00
*
* @ param s AC - 3 encoder private context
2011-03-25 21:12:26 +00:00
*/
2011-07-13 17:53:58 +00:00
int ff_ac3_validate_metadata ( AC3EncodeContext * s )
2011-03-25 21:12:26 +00:00
{
2011-07-13 17:53:58 +00:00
AVCodecContext * avctx = s - > avctx ;
2011-03-25 21:12:26 +00:00
AC3EncOptions * opt = & s - > options ;
2011-05-29 23:16:46 +00:00
opt - > audio_production_info = 0 ;
opt - > extended_bsi_1 = 0 ;
opt - > extended_bsi_2 = 0 ;
opt - > eac3_mixing_metadata = 0 ;
opt - > eac3_info_metadata = 0 ;
/* determine mixing metadata / xbsi1 use */
2011-08-09 22:11:08 +00:00
if ( s - > channel_mode > AC3_CHMODE_STEREO & & opt - > preferred_stereo_downmix ! = AC3ENC_OPT_NONE ) {
2011-05-29 23:16:46 +00:00
opt - > extended_bsi_1 = 1 ;
opt - > eac3_mixing_metadata = 1 ;
}
if ( s - > has_center & &
( opt - > ltrt_center_mix_level > = 0 | | opt - > loro_center_mix_level > = 0 ) ) {
opt - > extended_bsi_1 = 1 ;
opt - > eac3_mixing_metadata = 1 ;
2011-03-25 21:12:26 +00:00
}
2011-05-29 23:16:46 +00:00
if ( s - > has_surround & &
( opt - > ltrt_surround_mix_level > = 0 | | opt - > loro_surround_mix_level > = 0 ) ) {
opt - > extended_bsi_1 = 1 ;
opt - > eac3_mixing_metadata = 1 ;
2011-03-25 21:12:26 +00:00
}
2011-05-29 23:16:46 +00:00
if ( s - > eac3 ) {
/* determine info metadata use */
if ( avctx - > audio_service_type ! = AV_AUDIO_SERVICE_TYPE_MAIN )
opt - > eac3_info_metadata = 1 ;
2011-08-09 22:11:08 +00:00
if ( opt - > copyright ! = AC3ENC_OPT_NONE | | opt - > original ! = AC3ENC_OPT_NONE )
2011-05-29 23:16:46 +00:00
opt - > eac3_info_metadata = 1 ;
if ( s - > channel_mode = = AC3_CHMODE_STEREO & &
2011-08-09 22:11:08 +00:00
( opt - > dolby_headphone_mode ! = AC3ENC_OPT_NONE | | opt - > dolby_surround_mode ! = AC3ENC_OPT_NONE ) )
2011-05-29 23:16:46 +00:00
opt - > eac3_info_metadata = 1 ;
2011-08-09 22:11:08 +00:00
if ( s - > channel_mode > = AC3_CHMODE_2F2R & & opt - > dolby_surround_ex_mode ! = AC3ENC_OPT_NONE )
2011-05-29 23:16:46 +00:00
opt - > eac3_info_metadata = 1 ;
2011-08-09 22:11:08 +00:00
if ( opt - > mixing_level ! = AC3ENC_OPT_NONE | | opt - > room_type ! = AC3ENC_OPT_NONE | |
opt - > ad_converter_type ! = AC3ENC_OPT_NONE ) {
2011-05-29 23:16:46 +00:00
opt - > audio_production_info = 1 ;
opt - > eac3_info_metadata = 1 ;
2011-03-25 21:12:26 +00:00
}
} else {
2011-05-29 23:16:46 +00:00
/* determine audio production info use */
2011-08-09 22:11:08 +00:00
if ( opt - > mixing_level ! = AC3ENC_OPT_NONE | | opt - > room_type ! = AC3ENC_OPT_NONE )
2011-05-29 23:16:46 +00:00
opt - > audio_production_info = 1 ;
/* determine xbsi2 use */
2011-08-09 22:11:08 +00:00
if ( s - > channel_mode > = AC3_CHMODE_2F2R & & opt - > dolby_surround_ex_mode ! = AC3ENC_OPT_NONE )
2011-05-29 23:16:46 +00:00
opt - > extended_bsi_2 = 1 ;
2011-08-09 22:11:08 +00:00
if ( s - > channel_mode = = AC3_CHMODE_STEREO & & opt - > dolby_headphone_mode ! = AC3ENC_OPT_NONE )
2011-05-29 23:16:46 +00:00
opt - > extended_bsi_2 = 1 ;
2011-08-09 22:11:08 +00:00
if ( opt - > ad_converter_type ! = AC3ENC_OPT_NONE )
2011-05-29 23:16:46 +00:00
opt - > extended_bsi_2 = 1 ;
2011-03-25 21:12:26 +00:00
}
2011-05-29 23:16:46 +00:00
/* validate AC-3 mixing levels */
if ( ! s - > eac3 ) {
if ( s - > has_center ) {
validate_mix_level ( avctx , " center_mix_level " , & opt - > center_mix_level ,
2024-04-25 09:18:18 +00:00
cmixlev_options , CMIXLEV_NUM_OPTIONS , 1 , 0 ,
& s - > center_mix_level ) ;
2011-05-29 23:16:46 +00:00
}
if ( s - > has_surround ) {
validate_mix_level ( avctx , " surround_mix_level " , & opt - > surround_mix_level ,
2024-04-25 09:18:18 +00:00
surmixlev_options , SURMIXLEV_NUM_OPTIONS , 1 , 0 ,
& s - > surround_mix_level ) ;
2011-05-29 23:16:46 +00:00
}
}
/* validate extended bsi 1 / mixing metadata */
if ( opt - > extended_bsi_1 | | opt - > eac3_mixing_metadata ) {
2011-03-25 21:12:26 +00:00
/* default preferred stereo downmix */
2011-08-09 22:11:08 +00:00
if ( opt - > preferred_stereo_downmix = = AC3ENC_OPT_NONE )
opt - > preferred_stereo_downmix = AC3ENC_OPT_NOT_INDICATED ;
2011-05-29 23:16:46 +00:00
if ( ! s - > eac3 | | s - > has_center ) {
/* validate Lt/Rt center mix level */
validate_mix_level ( avctx , " ltrt_center_mix_level " ,
& opt - > ltrt_center_mix_level , extmixlev_options ,
EXTMIXLEV_NUM_OPTIONS , 5 , 0 ,
& s - > ltrt_center_mix_level ) ;
/* validate Lo/Ro center mix level */
validate_mix_level ( avctx , " loro_center_mix_level " ,
& opt - > loro_center_mix_level , extmixlev_options ,
EXTMIXLEV_NUM_OPTIONS , 5 , 0 ,
& s - > loro_center_mix_level ) ;
}
if ( ! s - > eac3 | | s - > has_surround ) {
/* validate Lt/Rt surround mix level */
validate_mix_level ( avctx , " ltrt_surround_mix_level " ,
& opt - > ltrt_surround_mix_level , extmixlev_options ,
EXTMIXLEV_NUM_OPTIONS , 6 , 3 ,
& s - > ltrt_surround_mix_level ) ;
/* validate Lo/Ro surround mix level */
validate_mix_level ( avctx , " loro_surround_mix_level " ,
& opt - > loro_surround_mix_level , extmixlev_options ,
EXTMIXLEV_NUM_OPTIONS , 6 , 3 ,
& s - > loro_surround_mix_level ) ;
}
2011-03-25 21:12:26 +00:00
}
2011-05-29 23:16:46 +00:00
/* validate audio service type / channels combination */
if ( ( avctx - > audio_service_type = = AV_AUDIO_SERVICE_TYPE_KARAOKE & &
2024-04-25 09:18:18 +00:00
avctx - > ch_layout . nb_channels = = 1 ) | |
2011-05-29 23:16:46 +00:00
( ( avctx - > audio_service_type = = AV_AUDIO_SERVICE_TYPE_COMMENTARY | |
avctx - > audio_service_type = = AV_AUDIO_SERVICE_TYPE_EMERGENCY | |
avctx - > audio_service_type = = AV_AUDIO_SERVICE_TYPE_VOICE_OVER )
2024-04-25 09:18:18 +00:00
& & avctx - > ch_layout . nb_channels > 1 ) ) {
2011-05-29 23:16:46 +00:00
av_log ( avctx , AV_LOG_ERROR , " invalid audio service type for the "
" specified number of channels \n " ) ;
return AVERROR ( EINVAL ) ;
}
/* validate extended bsi 2 / info metadata */
if ( opt - > extended_bsi_2 | | opt - > eac3_info_metadata ) {
2011-03-25 21:12:26 +00:00
/* default dolby headphone mode */
2011-08-09 22:11:08 +00:00
if ( opt - > dolby_headphone_mode = = AC3ENC_OPT_NONE )
opt - > dolby_headphone_mode = AC3ENC_OPT_NOT_INDICATED ;
2011-05-29 23:16:46 +00:00
/* default dolby surround ex mode */
2011-08-09 22:11:08 +00:00
if ( opt - > dolby_surround_ex_mode = = AC3ENC_OPT_NONE )
opt - > dolby_surround_ex_mode = AC3ENC_OPT_NOT_INDICATED ;
2011-03-25 21:12:26 +00:00
/* default A/D converter type */
2011-08-09 22:11:08 +00:00
if ( opt - > ad_converter_type = = AC3ENC_OPT_NONE )
opt - > ad_converter_type = AC3ENC_OPT_ADCONV_STANDARD ;
2011-05-29 23:16:46 +00:00
}
/* copyright & original defaults */
if ( ! s - > eac3 | | opt - > eac3_info_metadata ) {
/* default copyright */
2011-08-09 22:11:08 +00:00
if ( opt - > copyright = = AC3ENC_OPT_NONE )
opt - > copyright = AC3ENC_OPT_OFF ;
2011-05-29 23:16:46 +00:00
/* default original */
2011-08-09 22:11:08 +00:00
if ( opt - > original = = AC3ENC_OPT_NONE )
opt - > original = AC3ENC_OPT_ON ;
2011-05-29 23:16:46 +00:00
}
/* dolby surround mode default */
if ( ! s - > eac3 | | opt - > eac3_info_metadata ) {
2011-08-09 22:11:08 +00:00
if ( opt - > dolby_surround_mode = = AC3ENC_OPT_NONE )
opt - > dolby_surround_mode = AC3ENC_OPT_NOT_INDICATED ;
2011-05-29 23:16:46 +00:00
}
/* validate audio production info */
if ( opt - > audio_production_info ) {
2011-08-09 22:11:08 +00:00
if ( opt - > mixing_level = = AC3ENC_OPT_NONE ) {
2011-05-29 23:16:46 +00:00
av_log ( avctx , AV_LOG_ERROR , " mixing_level must be set if "
" room_type is set \n " ) ;
return AVERROR ( EINVAL ) ;
}
if ( opt - > mixing_level < 80 ) {
av_log ( avctx , AV_LOG_ERROR , " invalid mixing level. must be between "
" 80dB and 111dB \n " ) ;
return AVERROR ( EINVAL ) ;
}
/* default room type */
2011-08-09 22:11:08 +00:00
if ( opt - > room_type = = AC3ENC_OPT_NONE )
opt - > room_type = AC3ENC_OPT_NOT_INDICATED ;
2011-03-25 21:12:26 +00:00
}
/* set bitstream id for alternate bitstream syntax */
2011-05-29 23:16:46 +00:00
if ( ! s - > eac3 & & ( opt - > extended_bsi_1 | | opt - > extended_bsi_2 ) ) {
2011-03-25 21:12:26 +00:00
if ( s - > bitstream_id > 8 & & s - > bitstream_id < 11 ) {
2020-01-29 15:34:48 +00:00
if ( ! s - > warned_alternate_bitstream ) {
2011-03-25 21:12:26 +00:00
av_log ( avctx , AV_LOG_WARNING , " alternate bitstream syntax is "
" not compatible with reduced samplerates. writing of "
" extended bitstream information will be disabled. \n " ) ;
2020-01-29 15:34:48 +00:00
s - > warned_alternate_bitstream = 1 ;
2011-03-25 21:12:26 +00:00
}
} else {
s - > bitstream_id = 6 ;
}
}
return 0 ;
}
2010-12-14 14:51:30 +00:00
/**
* Finalize encoding and free any memory allocated by the encoder .
2011-11-02 14:38:10 +00:00
*
* @ param avctx Codec context
2010-12-14 14:51:30 +00:00
*/
2011-06-10 18:57:19 +00:00
av_cold int ff_ac3_encode_close ( AVCodecContext * avctx )
2002-12-09 12:03:43 +00:00
{
2010-12-16 02:32:55 +00:00
int blk , ch ;
2010-12-15 21:12:28 +00:00
AC3EncodeContext * s = avctx - > priv_data ;
2022-05-23 03:23:35 +00:00
av_freep ( & s - > mdct_window ) ;
2011-06-10 16:42:36 +00:00
av_freep ( & s - > windowed_samples ) ;
2013-06-29 15:50:07 +00:00
if ( s - > planar_samples )
2024-04-25 09:18:18 +00:00
for ( ch = 0 ; ch < s - > channels ; ch + + )
av_freep ( & s - > planar_samples [ ch ] ) ;
2010-12-16 02:32:55 +00:00
av_freep ( & s - > planar_samples ) ;
2010-12-15 21:12:28 +00:00
av_freep ( & s - > bap_buffer ) ;
av_freep ( & s - > bap1_buffer ) ;
2010-12-16 02:33:02 +00:00
av_freep ( & s - > mdct_coef_buffer ) ;
2011-01-05 20:35:36 +00:00
av_freep ( & s - > fixed_coef_buffer ) ;
2010-12-16 02:33:02 +00:00
av_freep ( & s - > exp_buffer ) ;
av_freep ( & s - > grouped_exp_buffer ) ;
av_freep ( & s - > psd_buffer ) ;
av_freep ( & s - > band_psd_buffer ) ;
av_freep ( & s - > mask_buffer ) ;
av_freep ( & s - > qmant_buffer ) ;
2011-07-13 19:49:08 +00:00
av_freep ( & s - > cpl_coord_exp_buffer ) ;
av_freep ( & s - > cpl_coord_mant_buffer ) ;
2014-11-29 17:54:27 +00:00
av_freep ( & s - > fdsp ) ;
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2010-12-15 21:12:28 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
2010-12-16 02:33:02 +00:00
av_freep ( & block - > mdct_coef ) ;
2011-01-05 20:35:36 +00:00
av_freep ( & block - > fixed_coef ) ;
2010-12-16 02:33:02 +00:00
av_freep ( & block - > exp ) ;
av_freep ( & block - > grouped_exp ) ;
av_freep ( & block - > psd ) ;
av_freep ( & block - > band_psd ) ;
av_freep ( & block - > mask ) ;
av_freep ( & block - > qmant ) ;
2011-07-13 19:49:08 +00:00
av_freep ( & block - > cpl_coord_exp ) ;
av_freep ( & block - > cpl_coord_mant ) ;
2010-12-15 21:12:28 +00:00
}
2022-05-23 03:23:35 +00:00
s - > mdct_end ( s ) ;
2010-12-16 03:44:29 +00:00
2003-01-19 18:30:29 +00:00
return 0 ;
2002-12-09 12:03:43 +00:00
}
2010-12-14 14:51:26 +00:00
2011-11-02 14:38:10 +00:00
/*
2010-12-14 14:51:30 +00:00
* Set channel information during initialization .
*/
2024-04-25 09:18:18 +00:00
static av_cold int set_channel_info ( AVCodecContext * avctx )
2010-12-14 14:51:23 +00:00
{
2024-04-25 09:18:18 +00:00
AC3EncodeContext * s = avctx - > priv_data ;
int channels = avctx - > ch_layout . nb_channels ;
uint64_t mask = avctx - > ch_layout . u . mask ;
2010-12-14 14:51:23 +00:00
if ( channels < 1 | | channels > AC3_MAX_CHANNELS )
2010-12-14 14:52:34 +00:00
return AVERROR ( EINVAL ) ;
2024-04-25 09:18:18 +00:00
if ( mask > 0x7FF )
2010-12-14 14:52:34 +00:00
return AVERROR ( EINVAL ) ;
2010-12-14 14:51:23 +00:00
2024-04-25 09:18:18 +00:00
if ( ! mask )
av_channel_layout_default ( & avctx - > ch_layout , channels ) ;
mask = avctx - > ch_layout . u . mask ;
s - > lfe_on = ! ! ( mask & AV_CH_LOW_FREQUENCY ) ;
2010-12-14 14:51:23 +00:00
s - > channels = channels ;
s - > fbw_channels = channels - s - > lfe_on ;
2011-05-23 15:45:51 +00:00
s - > lfe_channel = s - > lfe_on ? s - > fbw_channels + 1 : - 1 ;
2010-12-14 14:51:23 +00:00
if ( s - > lfe_on )
2024-04-25 09:18:18 +00:00
mask - = AV_CH_LOW_FREQUENCY ;
2010-12-14 14:51:23 +00:00
2024-04-25 09:18:18 +00:00
switch ( mask ) {
2010-12-14 14:51:23 +00:00
case AV_CH_LAYOUT_MONO : s - > channel_mode = AC3_CHMODE_MONO ; break ;
case AV_CH_LAYOUT_STEREO : s - > channel_mode = AC3_CHMODE_STEREO ; break ;
case AV_CH_LAYOUT_SURROUND : s - > channel_mode = AC3_CHMODE_3F ; break ;
case AV_CH_LAYOUT_2_1 : s - > channel_mode = AC3_CHMODE_2F1R ; break ;
case AV_CH_LAYOUT_4POINT0 : s - > channel_mode = AC3_CHMODE_3F1R ; break ;
case AV_CH_LAYOUT_QUAD :
case AV_CH_LAYOUT_2_2 : s - > channel_mode = AC3_CHMODE_2F2R ; break ;
case AV_CH_LAYOUT_5POINT0 :
case AV_CH_LAYOUT_5POINT0_BACK : s - > channel_mode = AC3_CHMODE_3F2R ; break ;
default :
2010-12-14 14:52:34 +00:00
return AVERROR ( EINVAL ) ;
2010-12-14 14:51:23 +00:00
}
2011-03-25 21:12:26 +00:00
s - > has_center = ( s - > channel_mode & 0x01 ) & & s - > channel_mode ! = AC3_CHMODE_MONO ;
s - > has_surround = s - > channel_mode & 0x04 ;
2010-12-14 14:51:23 +00:00
2022-05-23 03:23:35 +00:00
s - > channel_map = ac3_enc_channel_map [ s - > channel_mode ] [ s - > lfe_on ] ;
2010-12-14 14:51:23 +00:00
if ( s - > lfe_on )
2024-04-25 09:18:18 +00:00
mask | = AV_CH_LOW_FREQUENCY ;
av_channel_layout_from_mask ( & avctx - > ch_layout , mask ) ;
2010-12-14 14:51:23 +00:00
return 0 ;
}
2010-12-14 14:51:26 +00:00
2011-07-13 17:53:58 +00:00
static av_cold int validate_options ( AC3EncodeContext * s )
2010-12-14 14:51:23 +00:00
{
2011-07-13 17:53:58 +00:00
AVCodecContext * avctx = s - > avctx ;
2011-05-24 19:20:56 +00:00
int i , ret , max_sr ;
2010-12-14 14:51:23 +00:00
2010-12-14 14:52:43 +00:00
/* validate channel layout */
2024-04-25 09:18:18 +00:00
if ( ! avctx - > ch_layout . nb_channels ) {
2010-12-14 14:51:23 +00:00
av_log ( avctx , AV_LOG_WARNING , " No channel layout specified. The "
" encoder will guess the layout, but it "
" might be incorrect. \n " ) ;
}
2024-04-25 09:18:18 +00:00
ret = set_channel_info ( avctx ) ;
2010-12-14 14:52:34 +00:00
if ( ret ) {
2010-12-14 14:51:23 +00:00
av_log ( avctx , AV_LOG_ERROR , " invalid channel layout \n " ) ;
2010-12-14 14:52:34 +00:00
return ret ;
2010-12-14 14:51:23 +00:00
}
2010-12-14 14:52:43 +00:00
/* validate sample rate */
2011-05-24 19:20:56 +00:00
/* note: max_sr could be changed from 2 to 5 for E-AC-3 once we find a
decoder that supports half sample rate so we can validate that
the generated files are correct . */
max_sr = s - > eac3 ? 2 : 8 ;
for ( i = 0 ; i < = max_sr ; i + + ) {
if ( ( ff_ac3_sample_rate_tab [ i % 3 ] > > ( i / 3 ) ) = = avctx - > sample_rate )
2010-12-14 14:52:25 +00:00
break ;
2010-12-14 14:51:23 +00:00
}
2011-05-24 19:20:56 +00:00
if ( i > max_sr ) {
2010-12-14 14:52:34 +00:00
av_log ( avctx , AV_LOG_ERROR , " invalid sample rate \n " ) ;
return AVERROR ( EINVAL ) ;
2010-12-14 14:52:25 +00:00
}
2010-12-14 14:52:21 +00:00
s - > sample_rate = avctx - > sample_rate ;
2011-05-24 19:20:56 +00:00
s - > bit_alloc . sr_shift = i / 3 ;
s - > bit_alloc . sr_code = i % 3 ;
s - > bitstream_id = s - > eac3 ? 16 : 8 + s - > bit_alloc . sr_shift ;
2010-12-14 14:51:23 +00:00
2012-02-23 02:45:06 +00:00
/* select a default bit rate if not set by the user */
if ( ! avctx - > bit_rate ) {
switch ( s - > fbw_channels ) {
case 1 : avctx - > bit_rate = 96000 ; break ;
case 2 : avctx - > bit_rate = 192000 ; break ;
case 3 : avctx - > bit_rate = 320000 ; break ;
case 4 : avctx - > bit_rate = 384000 ; break ;
case 5 : avctx - > bit_rate = 448000 ; break ;
}
}
2010-12-14 14:52:43 +00:00
/* validate bit rate */
2011-05-24 19:20:56 +00:00
if ( s - > eac3 ) {
2015-09-19 13:57:56 +00:00
int max_br , min_br , wpf , min_br_code ;
2011-07-14 17:02:45 +00:00
int num_blks_code , num_blocks , frame_samples ;
2015-09-19 13:57:56 +00:00
long long min_br_dist ;
2011-05-24 19:20:56 +00:00
/* calculate min/max bitrate */
2011-07-14 17:02:45 +00:00
/* TODO: More testing with 3 and 2 blocks. All E-AC-3 samples I've
found use either 6 blocks or 1 block , even though 2 or 3 blocks
would work as far as the bit rate is concerned . */
for ( num_blks_code = 3 ; num_blks_code > = 0 ; num_blks_code - - ) {
num_blocks = ( ( int [ ] ) { 1 , 2 , 3 , 6 } ) [ num_blks_code ] ;
frame_samples = AC3_BLOCK_SIZE * num_blocks ;
max_br = 2048 * s - > sample_rate / frame_samples * 16 ;
min_br = ( ( s - > sample_rate + ( frame_samples - 1 ) ) / frame_samples ) * 16 ;
if ( avctx - > bit_rate < = max_br )
break ;
}
2011-05-24 19:20:56 +00:00
if ( avctx - > bit_rate < min_br | | avctx - > bit_rate > max_br ) {
av_log ( avctx , AV_LOG_ERROR , " invalid bit rate. must be %d to %d "
" for this sample rate \n " , min_br , max_br ) ;
return AVERROR ( EINVAL ) ;
}
2011-07-14 17:02:45 +00:00
s - > num_blks_code = num_blks_code ;
s - > num_blocks = num_blocks ;
2011-05-24 19:20:56 +00:00
/* calculate words-per-frame for the selected bitrate */
2011-07-14 17:02:45 +00:00
wpf = ( avctx - > bit_rate / 16 ) * frame_samples / s - > sample_rate ;
2011-05-24 19:20:56 +00:00
av_assert1 ( wpf > 0 & & wpf < = 2048 ) ;
/* find the closest AC-3 bitrate code to the selected bitrate.
this is needed for lookup tables for bandwidth and coupling
parameter selection */
min_br_code = - 1 ;
2015-09-19 13:57:56 +00:00
min_br_dist = INT64_MAX ;
2011-05-24 19:20:56 +00:00
for ( i = 0 ; i < 19 ; i + + ) {
2015-09-19 13:57:56 +00:00
long long br_dist = llabs ( ff_ac3_bitrate_tab [ i ] * 1000 - avctx - > bit_rate ) ;
2011-05-24 19:20:56 +00:00
if ( br_dist < min_br_dist ) {
min_br_dist = br_dist ;
min_br_code = i ;
}
}
/* make sure the minimum frame size is below the average frame size */
s - > frame_size_code = min_br_code < < 1 ;
while ( wpf > 1 & & wpf * s - > sample_rate / AC3_FRAME_SIZE * 16 > avctx - > bit_rate )
wpf - - ;
s - > frame_size_min = 2 * wpf ;
} else {
2015-09-19 13:57:56 +00:00
int best_br = 0 , best_code = 0 ;
long long best_diff = INT64_MAX ;
2011-05-24 23:38:30 +00:00
for ( i = 0 ; i < 19 ; i + + ) {
2012-02-23 02:26:09 +00:00
int br = ( ff_ac3_bitrate_tab [ i ] > > s - > bit_alloc . sr_shift ) * 1000 ;
2015-09-19 13:57:56 +00:00
long long diff = llabs ( br - avctx - > bit_rate ) ;
2012-02-23 02:26:09 +00:00
if ( diff < best_diff ) {
best_br = br ;
best_code = i ;
best_diff = diff ;
}
if ( ! best_diff )
2011-05-24 23:38:30 +00:00
break ;
}
2012-02-23 02:26:09 +00:00
avctx - > bit_rate = best_br ;
s - > frame_size_code = best_code < < 1 ;
2011-05-24 23:38:30 +00:00
s - > frame_size_min = 2 * ff_ac3_frame_size_tab [ s - > frame_size_code ] [ s - > bit_alloc . sr_code ] ;
2011-07-14 17:02:45 +00:00
s - > num_blks_code = 0x3 ;
s - > num_blocks = 6 ;
2010-12-14 14:52:34 +00:00
}
2011-05-24 19:20:56 +00:00
s - > bit_rate = avctx - > bit_rate ;
s - > frame_size = s - > frame_size_min ;
2010-12-14 14:52:18 +00:00
2010-12-17 23:42:52 +00:00
/* validate cutoff */
if ( avctx - > cutoff < 0 ) {
av_log ( avctx , AV_LOG_ERROR , " invalid cutoff frequency \n " ) ;
return AVERROR ( EINVAL ) ;
}
s - > cutoff = avctx - > cutoff ;
if ( s - > cutoff > ( s - > sample_rate > > 1 ) )
s - > cutoff = s - > sample_rate > > 1 ;
2011-07-25 16:54:25 +00:00
ret = ff_ac3_validate_metadata ( s ) ;
if ( ret )
return ret ;
2011-03-25 21:12:26 +00:00
2011-04-15 23:22:42 +00:00
s - > rematrixing_enabled = s - > options . stereo_rematrixing & &
( s - > channel_mode = = AC3_CHMODE_STEREO ) ;
2011-05-23 15:45:51 +00:00
s - > cpl_enabled = s - > options . channel_coupling & &
2011-08-07 21:47:42 +00:00
s - > channel_mode > = AC3_CHMODE_STEREO ;
2011-05-23 15:45:51 +00:00
2010-12-14 14:52:18 +00:00
return 0 ;
}
2011-11-02 14:38:10 +00:00
/*
2010-12-14 14:52:40 +00:00
* Set bandwidth for all channels .
* The user can optionally supply a cutoff frequency . Otherwise an appropriate
* default value will be used .
*/
2010-12-17 23:42:52 +00:00
static av_cold void set_bandwidth ( AC3EncodeContext * s )
2010-12-14 14:52:40 +00:00
{
2014-05-07 14:52:36 +00:00
int blk , ch , av_uninit ( cpl_start ) ;
2010-12-14 14:52:40 +00:00
2010-12-17 23:42:52 +00:00
if ( s - > cutoff ) {
2010-12-14 14:52:40 +00:00
/* calculate bandwidth based on user-specified cutoff frequency */
int fbw_coeffs ;
2010-12-17 23:42:52 +00:00
fbw_coeffs = s - > cutoff * 2 * AC3_MAX_COEFS / s - > sample_rate ;
2011-04-16 02:49:05 +00:00
s - > bandwidth_code = av_clip ( ( fbw_coeffs - 73 ) / 3 , 0 , 60 ) ;
2010-12-14 14:52:40 +00:00
} else {
/* use default bandwidth setting */
2011-04-16 02:49:05 +00:00
s - > bandwidth_code = ac3_bandwidth_tab [ s - > fbw_channels - 1 ] [ s - > bit_alloc . sr_code ] [ s - > frame_size_code / 2 ] ;
2010-12-14 14:52:40 +00:00
}
/* set number of coefficients for each channel */
2011-05-23 15:45:51 +00:00
for ( ch = 1 ; ch < = s - > fbw_channels ; ch + + ) {
s - > start_freq [ ch ] = 0 ;
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + )
2011-05-23 15:45:51 +00:00
s - > blocks [ blk ] . end_freq [ ch ] = s - > bandwidth_code * 3 + 73 ;
}
/* LFE channel always has 7 coefs */
if ( s - > lfe_on ) {
s - > start_freq [ s - > lfe_channel ] = 0 ;
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + )
2011-05-23 15:45:51 +00:00
s - > blocks [ blk ] . end_freq [ ch ] = 7 ;
}
/* initialize coupling strategy */
if ( s - > cpl_enabled ) {
2011-08-09 22:11:08 +00:00
if ( s - > options . cpl_start ! = AC3ENC_OPT_AUTO ) {
2011-05-23 15:45:51 +00:00
cpl_start = s - > options . cpl_start ;
} else {
cpl_start = ac3_coupling_start_tab [ s - > channel_mode - 2 ] [ s - > bit_alloc . sr_code ] [ s - > frame_size_code / 2 ] ;
2011-08-10 14:21:10 +00:00
if ( cpl_start < 0 ) {
2011-08-09 22:11:08 +00:00
if ( s - > options . channel_coupling = = AC3ENC_OPT_AUTO )
2011-08-10 14:21:10 +00:00
s - > cpl_enabled = 0 ;
else
cpl_start = 15 ;
}
2011-05-23 15:45:51 +00:00
}
}
if ( s - > cpl_enabled ) {
int i , cpl_start_band , cpl_end_band ;
uint8_t * cpl_band_sizes = s - > cpl_band_sizes ;
cpl_end_band = s - > bandwidth_code / 4 + 3 ;
cpl_start_band = av_clip ( cpl_start , 0 , FFMIN ( cpl_end_band - 1 , 15 ) ) ;
s - > num_cpl_subbands = cpl_end_band - cpl_start_band ;
s - > num_cpl_bands = 1 ;
* cpl_band_sizes = 12 ;
for ( i = cpl_start_band + 1 ; i < cpl_end_band ; i + + ) {
if ( ff_eac3_default_cpl_band_struct [ i ] ) {
* cpl_band_sizes + = 12 ;
} else {
s - > num_cpl_bands + + ;
cpl_band_sizes + + ;
* cpl_band_sizes = 12 ;
}
}
s - > start_freq [ CPL_CH ] = cpl_start_band * 12 + 37 ;
s - > cpl_end_freq = cpl_end_band * 12 + 37 ;
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + )
2011-05-23 15:45:51 +00:00
s - > blocks [ blk ] . end_freq [ CPL_CH ] = s - > cpl_end_freq ;
2010-12-14 14:52:40 +00:00
}
}
2011-07-13 17:53:58 +00:00
static av_cold int allocate_buffers ( AC3EncodeContext * s )
2010-12-15 21:12:28 +00:00
{
2010-12-16 02:32:55 +00:00
int blk , ch ;
2011-05-23 15:45:51 +00:00
int channels = s - > channels + 1 ; /* includes coupling channel */
2011-07-14 17:02:45 +00:00
int channel_blocks = channels * s - > num_blocks ;
int total_coefs = AC3_MAX_COEFS * channel_blocks ;
2010-12-15 21:12:28 +00:00
2011-06-13 21:44:50 +00:00
if ( s - > allocate_sample_buffers ( s ) )
2022-05-23 03:23:35 +00:00
return AVERROR ( ENOMEM ) ;
if ( ! FF_ALLOC_TYPED_ARRAY ( s - > bap_buffer , total_coefs ) | |
! FF_ALLOC_TYPED_ARRAY ( s - > bap1_buffer , total_coefs ) | |
! FF_ALLOCZ_TYPED_ARRAY ( s - > mdct_coef_buffer , total_coefs ) | |
! FF_ALLOC_TYPED_ARRAY ( s - > exp_buffer , total_coefs ) | |
! FF_ALLOC_TYPED_ARRAY ( s - > grouped_exp_buffer , channel_blocks * 128 ) | |
! FF_ALLOC_TYPED_ARRAY ( s - > psd_buffer , total_coefs ) | |
! FF_ALLOC_TYPED_ARRAY ( s - > band_psd_buffer , channel_blocks * 64 ) | |
! FF_ALLOC_TYPED_ARRAY ( s - > mask_buffer , channel_blocks * 64 ) | |
! FF_ALLOC_TYPED_ARRAY ( s - > qmant_buffer , total_coefs ) )
return AVERROR ( ENOMEM ) ;
2011-05-23 15:45:51 +00:00
if ( s - > cpl_enabled ) {
2022-05-23 03:23:35 +00:00
if ( ! FF_ALLOC_TYPED_ARRAY ( s - > cpl_coord_exp_buffer , channel_blocks * 16 ) | |
! FF_ALLOC_TYPED_ARRAY ( s - > cpl_coord_mant_buffer , channel_blocks * 16 ) )
return AVERROR ( ENOMEM ) ;
2011-05-23 15:45:51 +00:00
}
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2010-12-15 21:12:28 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
2022-05-23 03:23:35 +00:00
if ( ! FF_ALLOCZ_TYPED_ARRAY ( block - > mdct_coef , channels ) | |
! FF_ALLOCZ_TYPED_ARRAY ( block - > exp , channels ) | |
! FF_ALLOCZ_TYPED_ARRAY ( block - > grouped_exp , channels ) | |
! FF_ALLOCZ_TYPED_ARRAY ( block - > psd , channels ) | |
! FF_ALLOCZ_TYPED_ARRAY ( block - > band_psd , channels ) | |
! FF_ALLOCZ_TYPED_ARRAY ( block - > mask , channels ) | |
! FF_ALLOCZ_TYPED_ARRAY ( block - > qmant , channels ) )
return AVERROR ( ENOMEM ) ;
2011-05-23 15:45:51 +00:00
if ( s - > cpl_enabled ) {
2022-05-23 03:23:35 +00:00
if ( ! FF_ALLOCZ_TYPED_ARRAY ( block - > cpl_coord_exp , channels ) | |
! FF_ALLOCZ_TYPED_ARRAY ( block - > cpl_coord_mant , channels ) )
return AVERROR ( ENOMEM ) ;
2011-05-23 15:45:51 +00:00
}
2010-12-16 02:33:02 +00:00
2011-05-23 15:45:51 +00:00
for ( ch = 0 ; ch < channels ; ch + + ) {
2011-01-15 01:58:45 +00:00
/* arrangement: block, channel, coeff */
2011-05-23 15:45:51 +00:00
block - > grouped_exp [ ch ] = & s - > grouped_exp_buffer [ 128 * ( blk * channels + ch ) ] ;
block - > psd [ ch ] = & s - > psd_buffer [ AC3_MAX_COEFS * ( blk * channels + ch ) ] ;
block - > band_psd [ ch ] = & s - > band_psd_buffer [ 64 * ( blk * channels + ch ) ] ;
block - > mask [ ch ] = & s - > mask_buffer [ 64 * ( blk * channels + ch ) ] ;
block - > qmant [ ch ] = & s - > qmant_buffer [ AC3_MAX_COEFS * ( blk * channels + ch ) ] ;
if ( s - > cpl_enabled ) {
block - > cpl_coord_exp [ ch ] = & s - > cpl_coord_exp_buffer [ 16 * ( blk * channels + ch ) ] ;
block - > cpl_coord_mant [ ch ] = & s - > cpl_coord_mant_buffer [ 16 * ( blk * channels + ch ) ] ;
}
2011-01-15 01:58:45 +00:00
/* arrangement: channel, block, coeff */
2011-07-14 17:02:45 +00:00
block - > exp [ ch ] = & s - > exp_buffer [ AC3_MAX_COEFS * ( s - > num_blocks * ch + blk ) ] ;
block - > mdct_coef [ ch ] = & s - > mdct_coef_buffer [ AC3_MAX_COEFS * ( s - > num_blocks * ch + blk ) ] ;
2010-12-16 02:33:02 +00:00
}
2010-12-15 21:12:28 +00:00
}
2011-06-10 18:57:19 +00:00
if ( ! s - > fixed_point ) {
2022-05-23 03:23:35 +00:00
if ( ! FF_ALLOCZ_TYPED_ARRAY ( s - > fixed_coef_buffer , total_coefs ) )
return AVERROR ( ENOMEM ) ;
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2011-01-05 20:35:36 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
2022-05-23 03:23:35 +00:00
if ( ! FF_ALLOCZ_TYPED_ARRAY ( block - > fixed_coef , channels ) )
return AVERROR ( ENOMEM ) ;
2011-05-23 15:45:51 +00:00
for ( ch = 0 ; ch < channels ; ch + + )
2011-07-14 17:02:45 +00:00
block - > fixed_coef [ ch ] = & s - > fixed_coef_buffer [ AC3_MAX_COEFS * ( s - > num_blocks * ch + blk ) ] ;
2011-01-05 20:35:36 +00:00
}
} else {
2011-07-14 17:02:45 +00:00
for ( blk = 0 ; blk < s - > num_blocks ; blk + + ) {
2011-01-05 20:35:36 +00:00
AC3Block * block = & s - > blocks [ blk ] ;
2022-05-23 03:23:35 +00:00
if ( ! FF_ALLOCZ_TYPED_ARRAY ( block - > fixed_coef , channels ) )
return AVERROR ( ENOMEM ) ;
2011-05-23 15:45:51 +00:00
for ( ch = 0 ; ch < channels ; ch + + )
2011-01-05 20:35:36 +00:00
block - > fixed_coef [ ch ] = ( int32_t * ) block - > mdct_coef [ ch ] ;
}
}
2010-12-15 21:12:28 +00:00
return 0 ;
}
2011-06-10 18:57:19 +00:00
av_cold int ff_ac3_encode_init ( AVCodecContext * avctx )
2010-12-14 14:52:18 +00:00
{
2022-05-23 03:23:35 +00:00
static AVOnce init_static_once = AV_ONCE_INIT ;
2010-12-14 14:52:18 +00:00
AC3EncodeContext * s = avctx - > priv_data ;
2010-12-21 18:26:13 +00:00
int ret , frame_size_58 ;
2010-12-14 14:52:18 +00:00
2011-06-13 21:44:50 +00:00
s - > avctx = avctx ;
2012-08-05 09:11:04 +00:00
s - > eac3 = avctx - > codec_id = = AV_CODEC_ID_EAC3 ;
2011-05-24 19:20:56 +00:00
2011-07-13 17:53:58 +00:00
ret = validate_options ( s ) ;
2010-12-14 14:52:18 +00:00
if ( ret )
2022-05-23 03:23:35 +00:00
return ret ;
2010-12-14 14:52:18 +00:00
2011-07-14 17:02:45 +00:00
avctx - > frame_size = AC3_BLOCK_SIZE * s - > num_blocks ;
2014-08-23 12:40:50 +00:00
avctx - > initial_padding = AC3_BLOCK_SIZE ;
2011-07-14 17:02:45 +00:00
2011-03-24 16:10:38 +00:00
s - > bitstream_mode = avctx - > audio_service_type ;
if ( s - > bitstream_mode = = AV_AUDIO_SERVICE_TYPE_KARAOKE )
s - > bitstream_mode = 0x7 ;
2010-12-14 14:52:37 +00:00
2010-12-14 14:51:23 +00:00
s - > bits_written = 0 ;
s - > samples_written = 0 ;
2010-12-21 18:26:13 +00:00
/* calculate crc_inv for both possible frame sizes */
frame_size_58 = ( ( s - > frame_size > > 2 ) + ( s - > frame_size > > 4 ) ) < < 1 ;
s - > crc_inv [ 0 ] = pow_poly ( ( CRC16_POLY > > 1 ) , ( 8 * frame_size_58 ) - 16 , CRC16_POLY ) ;
if ( s - > bit_alloc . sr_code = = 1 ) {
frame_size_58 = ( ( ( s - > frame_size + 2 ) > > 2 ) + ( ( s - > frame_size + 2 ) > > 4 ) ) < < 1 ;
s - > crc_inv [ 1 ] = pow_poly ( ( CRC16_POLY > > 1 ) , ( 8 * frame_size_58 ) - 16 , CRC16_POLY ) ;
}
2022-05-23 03:23:35 +00:00
if ( CONFIG_EAC3_ENCODER & & s - > eac3 ) {
static AVOnce init_static_once_eac3 = AV_ONCE_INIT ;
ff_thread_once ( & init_static_once_eac3 , ff_eac3_exponent_init ) ;
2011-06-10 15:45:03 +00:00
s - > output_frame_header = ff_eac3_output_frame_header ;
2022-05-23 03:23:35 +00:00
} else
2011-06-10 15:45:03 +00:00
s - > output_frame_header = ac3_output_frame_header ;
2010-12-17 23:42:52 +00:00
set_bandwidth ( s ) ;
2010-12-14 14:51:23 +00:00
2010-12-14 14:53:43 +00:00
bit_alloc_init ( s ) ;
2010-12-14 14:51:23 +00:00
2011-07-13 19:12:11 +00:00
ret = s - > mdct_init ( s ) ;
2010-12-16 03:44:35 +00:00
if ( ret )
2022-05-23 03:23:35 +00:00
return ret ;
2010-12-14 14:51:23 +00:00
2011-07-13 17:53:58 +00:00
ret = allocate_buffers ( s ) ;
2010-12-16 03:44:35 +00:00
if ( ret )
2022-05-23 03:23:35 +00:00
return ret ;
2010-12-15 21:12:28 +00:00
2014-01-16 16:30:19 +00:00
ff_audiodsp_init ( & s - > adsp ) ;
2014-02-08 01:59:58 +00:00
ff_me_cmp_init ( & s - > mecc , avctx ) ;
2015-06-29 19:59:37 +00:00
ff_ac3dsp_init ( & s - > ac3dsp , avctx - > flags & AV_CODEC_FLAG_BITEXACT ) ;
2010-12-16 15:06:28 +00:00
2011-07-13 17:53:58 +00:00
dprint_options ( s ) ;
2011-03-25 21:12:26 +00:00
2022-05-23 03:23:35 +00:00
ff_thread_once ( & init_static_once , exponent_init ) ;
2010-12-14 14:51:23 +00:00
return 0 ;
}