2012-02-05 13:31:33 +03:00
/*
2006-06-24 13:20:15 +03:00
* FLAC audio encoder
2008-08-17 01:42:59 +03:00
* Copyright ( c ) 2006 Justin Ruggles < justin . ruggles @ gmail . com >
2006-06-24 13:20:15 +03:00
*
2006-10-07 18:30:46 +03:00
* This file is part of FFmpeg .
*
* FFmpeg is free software ; you can redistribute it and / or
2006-06-24 13:20:15 +03:00
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
2006-10-07 18:30:46 +03:00
* version 2.1 of the License , or ( at your option ) any later version .
2006-06-24 13:20:15 +03:00
*
2006-10-07 18:30:46 +03:00
* FFmpeg is distributed in the hope that it will be useful ,
2006-06-24 13:20:15 +03:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
2006-10-07 18:30:46 +03:00
* License along with FFmpeg ; if not , write to the Free Software
2006-06-24 13:20:15 +03:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
2012-08-02 22:58:17 +03:00
# include "libavutil/avassert.h"
2021-06-12 01:10:58 +02:00
# include "libavutil/channel_layout.h"
2008-05-09 14:56:36 +03:00
# include "libavutil/crc.h"
2012-10-25 22:07:59 +03:00
# include "libavutil/intmath.h"
2008-09-15 00:39:54 +03:00
# include "libavutil/md5.h"
2011-04-02 13:28:01 +03:00
# include "libavutil/opt.h"
2016-06-04 11:45:16 +02:00
2006-06-24 13:20:15 +03:00
# include "avcodec.h"
2014-02-13 19:57:05 +03:00
# include "bswapdsp.h"
2022-03-16 19:18:28 +02:00
# include "codec_internal.h"
2021-04-25 01:43:26 +02:00
# include "encode.h"
2013-01-22 23:27:01 +03:00
# include "put_bits.h"
2008-08-16 20:18:20 +03:00
# include "lpc.h"
2009-03-19 05:04:21 +02:00
# include "flac.h"
2009-03-21 03:16:38 +02:00
# include "flacdata.h"
2022-08-01 03:07:46 +02:00
# include "flacencdsp.h"
2006-06-24 13:20:15 +03:00
# define FLAC_SUBFRAME_CONSTANT 0
# define FLAC_SUBFRAME_VERBATIM 1
# define FLAC_SUBFRAME_FIXED 8
# define FLAC_SUBFRAME_LPC 32
2006-07-02 13:22:31 +03:00
# define MAX_FIXED_ORDER 4
# define MAX_PARTITION_ORDER 8
# define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER)
# define MAX_LPC_PRECISION 15
2016-08-22 23:02:04 +02:00
# define MIN_LPC_SHIFT 0
2006-07-02 13:22:31 +03:00
# define MAX_LPC_SHIFT 15
2012-10-27 07:46:43 +03:00
enum CodingMode {
CODING_MODE_RICE = 4 ,
CODING_MODE_RICE2 = 5 ,
} ;
2006-07-02 13:22:31 +03:00
typedef struct CompressionOptions {
int compression_level ;
int block_time_ms ;
2011-04-02 13:28:01 +03:00
enum FFLPCType lpc_type ;
2010-07-11 19:56:20 +03:00
int lpc_passes ;
2006-07-02 13:22:31 +03:00
int lpc_coeff_precision ;
int min_prediction_order ;
int max_prediction_order ;
int prediction_order_method ;
int min_partition_order ;
int max_partition_order ;
2012-07-02 16:52:05 +03:00
int ch_mode ;
2015-05-19 13:26:55 +02:00
int exact_rice_parameters ;
2015-05-20 01:23:39 +02:00
int multi_dim_quant ;
2006-07-02 13:22:31 +03:00
} CompressionOptions ;
2006-06-28 00:01:21 +03:00
typedef struct RiceContext {
2012-10-27 07:46:43 +03:00
enum CodingMode coding_mode ;
2006-06-28 00:01:21 +03:00
int porder ;
2006-07-02 13:22:31 +03:00
int params [ MAX_PARTITIONS ] ;
2006-06-28 00:01:21 +03:00
} RiceContext ;
2006-06-24 13:20:15 +03:00
typedef struct FlacSubframe {
int type ;
int type_code ;
int obits ;
2012-10-25 22:07:59 +03:00
int wasted ;
2006-06-24 13:20:15 +03:00
int order ;
2006-07-02 13:22:31 +03:00
int32_t coefs [ MAX_LPC_ORDER ] ;
int shift ;
2015-05-19 13:48:30 +02:00
2006-06-28 00:01:21 +03:00
RiceContext rc ;
2015-05-19 13:48:30 +02:00
uint32_t rc_udata [ FLAC_MAX_BLOCKSIZE ] ;
uint64_t rc_sums [ 32 ] [ MAX_PARTITIONS ] ;
2006-06-24 13:20:15 +03:00
int32_t samples [ FLAC_MAX_BLOCKSIZE ] ;
2014-08-13 00:22:03 +03:00
int32_t residual [ FLAC_MAX_BLOCKSIZE + 11 ] ;
2006-06-24 13:20:15 +03:00
} FlacSubframe ;
typedef struct FlacFrame {
2009-03-19 05:04:21 +02:00
FlacSubframe subframes [ FLAC_MAX_CHANNELS ] ;
2022-10-11 19:24:36 +02:00
int64_t samples_33bps [ FLAC_MAX_BLOCKSIZE ] ;
2006-06-24 13:20:15 +03:00
int blocksize ;
int bs_code [ 2 ] ;
uint8_t crc8 ;
int ch_mode ;
2010-07-31 19:46:32 +03:00
int verbatim_only ;
2006-06-24 13:20:15 +03:00
} FlacFrame ;
typedef struct FlacEncodeContext {
2011-04-02 13:28:01 +03:00
AVClass * class ;
2006-06-24 13:20:15 +03:00
PutBitContext pb ;
2009-03-21 03:20:28 +02:00
int channels ;
int samplerate ;
2006-06-24 13:20:15 +03:00
int sr_code [ 2 ] ;
2012-10-27 07:26:02 +03:00
int bps_code ;
2009-04-16 05:28:49 +03:00
int max_blocksize ;
2008-09-15 01:25:50 +03:00
int min_framesize ;
2009-03-21 03:20:28 +02:00
int max_framesize ;
2008-09-15 01:25:50 +03:00
int max_encoded_framesize ;
2006-06-24 13:20:15 +03:00
uint32_t frame_count ;
2008-09-14 23:00:36 +03:00
uint64_t sample_count ;
2008-09-15 00:39:54 +03:00
uint8_t md5sum [ 16 ] ;
2006-06-24 13:20:15 +03:00
FlacFrame frame ;
2006-07-02 13:22:31 +03:00
CompressionOptions options ;
2006-06-28 00:01:21 +03:00
AVCodecContext * avctx ;
2011-01-21 02:11:44 +02:00
LPCContext lpc_ctx ;
2008-09-15 00:39:54 +03:00
struct AVMD5 * md5ctx ;
2012-10-25 22:00:10 +03:00
uint8_t * md5_buffer ;
unsigned int md5_buffer_size ;
2014-02-13 19:57:05 +03:00
BswapDSPContext bdsp ;
2022-08-01 03:07:46 +02:00
FLACEncDSPContext flac_dsp ;
2014-04-29 16:11:30 +03:00
int flushed ;
int64_t next_pts ;
2006-06-24 13:20:15 +03:00
} FlacEncodeContext ;
2010-07-30 21:30:09 +03:00
2006-06-24 13:20:15 +03:00
/**
2010-07-30 21:30:09 +03:00
* Write streaminfo metadata block to byte array .
2006-06-24 13:20:15 +03:00
*/
static void write_streaminfo ( FlacEncodeContext * s , uint8_t * header )
{
PutBitContext pb ;
memset ( header , 0 , FLAC_STREAMINFO_SIZE ) ;
init_put_bits ( & pb , header , FLAC_STREAMINFO_SIZE ) ;
/* streaminfo metadata block */
2009-04-16 05:28:49 +03:00
put_bits ( & pb , 16 , s - > max_blocksize ) ;
put_bits ( & pb , 16 , s - > max_blocksize ) ;
2008-09-15 01:25:50 +03:00
put_bits ( & pb , 24 , s - > min_framesize ) ;
2006-06-24 13:20:15 +03:00
put_bits ( & pb , 24 , s - > max_framesize ) ;
put_bits ( & pb , 20 , s - > samplerate ) ;
put_bits ( & pb , 3 , s - > channels - 1 ) ;
2012-10-27 07:26:02 +03:00
put_bits ( & pb , 5 , s - > avctx - > bits_per_raw_sample - 1 ) ;
2008-09-14 23:00:36 +03:00
/* write 36-bit sample count in 2 put_bits() calls */
put_bits ( & pb , 24 , ( s - > sample_count & 0xFFFFFF000LL ) > > 12 ) ;
put_bits ( & pb , 12 , s - > sample_count & 0x000000FFFLL ) ;
2006-06-24 13:20:15 +03:00
flush_put_bits ( & pb ) ;
2008-09-15 00:39:54 +03:00
memcpy ( & header [ 18 ] , s - > md5sum , 16 ) ;
2006-06-24 13:20:15 +03:00
}
2010-07-30 21:30:09 +03:00
2022-08-28 15:21:27 +02:00
/**
* Calculate an estimate for the maximum frame size based on verbatim mode .
* @ param blocksize block size , in samples
* @ param ch number of channels
* @ param bps bits - per - sample
*/
static int flac_get_max_frame_size ( int blocksize , int ch , int bps )
{
/* Technically, there is no limit to FLAC frame size, but an encoder
should not write a frame that is larger than if verbatim encoding mode
were to be used . */
int count ;
count = 16 ; /* frame header */
count + = ch * ( ( 7 + bps + 7 ) / 8 ) ; /* subframe headers */
if ( ch = = 2 ) {
/* for stereo, need to account for using decorrelation */
count + = ( ( 2 * bps + 1 ) * blocksize + 7 ) / 8 ;
} else {
count + = ( ch * bps * blocksize + 7 ) / 8 ;
}
count + = 2 ; /* frame footer */
return count ;
}
2006-06-24 13:20:15 +03:00
/**
2010-07-30 21:30:09 +03:00
* Set blocksize based on samplerate .
* Choose the closest predefined blocksize > = BLOCK_TIME_MS milliseconds .
2006-06-24 13:20:15 +03:00
*/
2006-07-02 13:22:31 +03:00
static int select_blocksize ( int samplerate , int block_time_ms )
2006-06-24 13:20:15 +03:00
{
int i ;
int target ;
int blocksize ;
2012-08-02 22:58:17 +03:00
av_assert0 ( samplerate > 0 ) ;
2009-03-21 03:16:38 +02:00
blocksize = ff_flac_blocksize_table [ 1 ] ;
2010-07-30 21:30:09 +03:00
target = ( samplerate * block_time_ms ) / 1000 ;
for ( i = 0 ; i < 16 ; i + + ) {
if ( target > = ff_flac_blocksize_table [ i ] & &
ff_flac_blocksize_table [ i ] > blocksize ) {
2009-03-21 03:16:38 +02:00
blocksize = ff_flac_blocksize_table [ i ] ;
2006-06-24 13:20:15 +03:00
}
}
return blocksize ;
}
2010-07-30 21:30:09 +03:00
2010-07-30 21:59:27 +03:00
static av_cold void dprint_compression_options ( FlacEncodeContext * s )
{
AVCodecContext * avctx = s - > avctx ;
CompressionOptions * opt = & s - > options ;
av_log ( avctx , AV_LOG_DEBUG , " compression: %d \n " , opt - > compression_level ) ;
switch ( opt - > lpc_type ) {
2011-04-02 13:28:01 +03:00
case FF_LPC_TYPE_NONE :
2010-07-30 21:59:27 +03:00
av_log ( avctx , AV_LOG_DEBUG , " lpc type: None \n " ) ;
break ;
2011-04-02 13:28:01 +03:00
case FF_LPC_TYPE_FIXED :
2010-07-30 21:59:27 +03:00
av_log ( avctx , AV_LOG_DEBUG , " lpc type: Fixed pre-defined coefficients \n " ) ;
break ;
2011-04-02 13:28:01 +03:00
case FF_LPC_TYPE_LEVINSON :
2010-07-30 21:59:27 +03:00
av_log ( avctx , AV_LOG_DEBUG , " lpc type: Levinson-Durbin recursion with Welch window \n " ) ;
break ;
2011-04-02 13:28:01 +03:00
case FF_LPC_TYPE_CHOLESKY :
2010-07-30 21:59:27 +03:00
av_log ( avctx , AV_LOG_DEBUG , " lpc type: Cholesky factorization, %d pass%s \n " ,
opt - > lpc_passes , opt - > lpc_passes = = 1 ? " " : " es " ) ;
break ;
}
av_log ( avctx , AV_LOG_DEBUG , " prediction order: %d, %d \n " ,
opt - > min_prediction_order , opt - > max_prediction_order ) ;
switch ( opt - > prediction_order_method ) {
case ORDER_METHOD_EST :
av_log ( avctx , AV_LOG_DEBUG , " order method: %s \n " , " estimate " ) ;
break ;
case ORDER_METHOD_2LEVEL :
av_log ( avctx , AV_LOG_DEBUG , " order method: %s \n " , " 2-level " ) ;
break ;
case ORDER_METHOD_4LEVEL :
av_log ( avctx , AV_LOG_DEBUG , " order method: %s \n " , " 4-level " ) ;
break ;
case ORDER_METHOD_8LEVEL :
av_log ( avctx , AV_LOG_DEBUG , " order method: %s \n " , " 8-level " ) ;
break ;
case ORDER_METHOD_SEARCH :
av_log ( avctx , AV_LOG_DEBUG , " order method: %s \n " , " full search " ) ;
break ;
case ORDER_METHOD_LOG :
av_log ( avctx , AV_LOG_DEBUG , " order method: %s \n " , " log search " ) ;
break ;
}
av_log ( avctx , AV_LOG_DEBUG , " partition order: %d, %d \n " ,
opt - > min_partition_order , opt - > max_partition_order ) ;
av_log ( avctx , AV_LOG_DEBUG , " block size: %d \n " , avctx - > frame_size ) ;
av_log ( avctx , AV_LOG_DEBUG , " lpc precision: %d \n " ,
opt - > lpc_coeff_precision ) ;
}
2008-03-21 05:11:20 +02:00
static av_cold int flac_encode_init ( AVCodecContext * avctx )
2006-06-24 13:20:15 +03:00
{
int freq = avctx - > sample_rate ;
2013-05-07 08:20:32 +03:00
int channels = avctx - > ch_layout . nb_channels ;
2006-06-24 13:20:15 +03:00
FlacEncodeContext * s = avctx - > priv_data ;
2011-01-21 02:12:03 +02:00
int i , level , ret ;
2006-06-24 13:20:15 +03:00
uint8_t * streaminfo ;
2006-06-28 00:01:21 +03:00
s - > avctx = avctx ;
2012-10-27 07:26:02 +03:00
switch ( avctx - > sample_fmt ) {
case AV_SAMPLE_FMT_S16 :
avctx - > bits_per_raw_sample = 16 ;
s - > bps_code = 4 ;
break ;
case AV_SAMPLE_FMT_S32 :
2022-10-11 19:24:36 +02:00
if ( avctx - > bits_per_raw_sample < = 24 ) {
if ( avctx - > bits_per_raw_sample < 24 )
av_log ( avctx , AV_LOG_WARNING , " encoding as 24 bits-per-sample \n " ) ;
avctx - > bits_per_raw_sample = 24 ;
s - > bps_code = 6 ;
} else if ( avctx - > strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL ) {
av_log ( avctx , AV_LOG_WARNING ,
" encoding as 24 bits-per-sample, more is considered "
" experimental. Add -strict experimental if you want "
" to encode more than 24 bits-per-sample \n " ) ;
avctx - > bits_per_raw_sample = 24 ;
s - > bps_code = 6 ;
} else {
avctx - > bits_per_raw_sample = 32 ;
s - > bps_code = 7 ;
}
2012-10-27 07:26:02 +03:00
break ;
}
2006-06-24 13:20:15 +03:00
2012-12-31 14:13:36 +03:00
if ( channels < 1 | | channels > FLAC_MAX_CHANNELS ) {
av_log ( avctx , AV_LOG_ERROR , " %d channels not supported (max %d) \n " ,
channels , FLAC_MAX_CHANNELS ) ;
return AVERROR ( EINVAL ) ;
}
2006-06-24 13:20:15 +03:00
s - > channels = channels ;
/* find samplerate in table */
2010-07-30 21:30:09 +03:00
if ( freq < 1 )
2017-09-23 01:44:27 +02:00
return AVERROR ( EINVAL ) ;
2022-10-31 18:09:15 +02:00
for ( i = 1 ; i < 12 ; i + + ) {
2010-07-30 21:30:09 +03:00
if ( freq = = ff_flac_sample_rate_table [ i ] ) {
2009-03-21 03:16:38 +02:00
s - > samplerate = ff_flac_sample_rate_table [ i ] ;
2006-06-24 13:20:15 +03:00
s - > sr_code [ 0 ] = i ;
s - > sr_code [ 1 ] = 0 ;
break ;
}
}
/* if not in table, samplerate is non-standard */
2010-07-30 21:30:09 +03:00
if ( i = = 12 ) {
if ( freq % 1000 = = 0 & & freq < 255000 ) {
2006-06-24 13:20:15 +03:00
s - > sr_code [ 0 ] = 12 ;
s - > sr_code [ 1 ] = freq / 1000 ;
2010-07-30 21:30:09 +03:00
} else if ( freq % 10 = = 0 & & freq < 655350 ) {
2006-06-24 13:20:15 +03:00
s - > sr_code [ 0 ] = 14 ;
s - > sr_code [ 1 ] = freq / 10 ;
2010-07-30 21:30:09 +03:00
} else if ( freq < 65535 ) {
2006-06-24 13:20:15 +03:00
s - > sr_code [ 0 ] = 13 ;
s - > sr_code [ 1 ] = freq ;
2022-10-31 18:09:15 +02:00
} else if ( freq < 1048576 ) {
s - > sr_code [ 0 ] = 0 ;
s - > sr_code [ 1 ] = 0 ;
2006-06-24 13:20:15 +03:00
} else {
2012-12-31 14:13:36 +03:00
av_log ( avctx , AV_LOG_ERROR , " %d Hz not supported \n " , freq ) ;
return AVERROR ( EINVAL ) ;
2006-06-24 13:20:15 +03:00
}
s - > samplerate = freq ;
}
2006-07-02 13:22:31 +03:00
/* set compression option defaults based on avctx->compression_level */
2010-07-30 21:30:09 +03:00
if ( avctx - > compression_level < 0 )
2006-07-02 13:22:31 +03:00
s - > options . compression_level = 5 ;
2010-07-30 21:30:09 +03:00
else
2006-07-02 13:22:31 +03:00
s - > options . compression_level = avctx - > compression_level ;
2010-07-30 21:30:09 +03:00
level = s - > options . compression_level ;
if ( level > 12 ) {
2006-07-02 13:22:31 +03:00
av_log ( avctx , AV_LOG_ERROR , " invalid compression level: %d \n " ,
s - > options . compression_level ) ;
2012-12-31 14:13:36 +03:00
return AVERROR ( EINVAL ) ;
2006-07-02 13:22:31 +03:00
}
2010-07-30 21:30:09 +03:00
s - > options . block_time_ms = ( ( int [ ] ) { 27 , 27 , 27 , 105 , 105 , 105 , 105 , 105 , 105 , 105 , 105 , 105 , 105 } ) [ level ] ;
2011-04-02 13:28:01 +03:00
if ( s - > options . lpc_type = = FF_LPC_TYPE_DEFAULT )
s - > options . lpc_type = ( ( int [ ] ) { FF_LPC_TYPE_FIXED , FF_LPC_TYPE_FIXED , FF_LPC_TYPE_FIXED ,
FF_LPC_TYPE_LEVINSON , FF_LPC_TYPE_LEVINSON , FF_LPC_TYPE_LEVINSON ,
FF_LPC_TYPE_LEVINSON , FF_LPC_TYPE_LEVINSON , FF_LPC_TYPE_LEVINSON ,
FF_LPC_TYPE_LEVINSON , FF_LPC_TYPE_LEVINSON , FF_LPC_TYPE_LEVINSON ,
FF_LPC_TYPE_LEVINSON } ) [ level ] ;
2010-07-30 21:30:09 +03:00
2016-01-31 21:04:17 +02:00
if ( s - > options . min_prediction_order < 0 )
s - > options . min_prediction_order = ( ( int [ ] ) { 2 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 } ) [ level ] ;
if ( s - > options . max_prediction_order < 0 )
s - > options . max_prediction_order = ( ( int [ ] ) { 3 , 4 , 4 , 6 , 8 , 8 , 8 , 8 , 12 , 12 , 12 , 32 , 32 } ) [ level ] ;
2010-07-30 21:30:09 +03:00
2011-04-02 13:28:01 +03:00
if ( s - > options . prediction_order_method < 0 )
s - > options . prediction_order_method = ( ( int [ ] ) { ORDER_METHOD_EST , ORDER_METHOD_EST , ORDER_METHOD_EST ,
ORDER_METHOD_EST , ORDER_METHOD_EST , ORDER_METHOD_EST ,
ORDER_METHOD_4LEVEL , ORDER_METHOD_LOG , ORDER_METHOD_4LEVEL ,
ORDER_METHOD_LOG , ORDER_METHOD_SEARCH , ORDER_METHOD_LOG ,
ORDER_METHOD_SEARCH } ) [ level ] ;
2010-07-30 21:30:09 +03:00
2011-04-02 13:28:01 +03:00
if ( s - > options . min_partition_order > s - > options . max_partition_order ) {
av_log ( avctx , AV_LOG_ERROR , " invalid partition orders: min=%d max=%d \n " ,
s - > options . min_partition_order , s - > options . max_partition_order ) ;
return AVERROR ( EINVAL ) ;
}
if ( s - > options . min_partition_order < 0 )
s - > options . min_partition_order = ( ( int [ ] ) { 2 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ) [ level ] ;
if ( s - > options . max_partition_order < 0 )
s - > options . max_partition_order = ( ( int [ ] ) { 2 , 2 , 3 , 3 , 3 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 } ) [ level ] ;
2006-07-02 14:06:27 +03:00
2015-09-13 23:45:24 +02:00
if ( s - > options . lpc_type = = FF_LPC_TYPE_NONE ) {
s - > options . min_prediction_order = 0 ;
s - > options . max_prediction_order = 0 ;
} else if ( s - > options . lpc_type = = FF_LPC_TYPE_FIXED ) {
if ( s - > options . min_prediction_order > MAX_FIXED_ORDER ) {
av_log ( avctx , AV_LOG_WARNING ,
" invalid min prediction order %d, clamped to %d \n " ,
s - > options . min_prediction_order , MAX_FIXED_ORDER ) ;
s - > options . min_prediction_order = MAX_FIXED_ORDER ;
}
if ( s - > options . max_prediction_order > MAX_FIXED_ORDER ) {
av_log ( avctx , AV_LOG_WARNING ,
" invalid max prediction order %d, clamped to %d \n " ,
s - > options . max_prediction_order , MAX_FIXED_ORDER ) ;
s - > options . max_prediction_order = MAX_FIXED_ORDER ;
}
}
2010-07-30 21:30:09 +03:00
if ( s - > options . max_prediction_order < s - > options . min_prediction_order ) {
2006-07-02 13:22:31 +03:00
av_log ( avctx , AV_LOG_ERROR , " invalid prediction orders: min=%d max=%d \n " ,
s - > options . min_prediction_order , s - > options . max_prediction_order ) ;
2012-12-31 14:13:36 +03:00
return AVERROR ( EINVAL ) ;
2006-07-02 13:22:31 +03:00
}
2010-07-30 21:30:09 +03:00
if ( avctx - > frame_size > 0 ) {
if ( avctx - > frame_size < FLAC_MIN_BLOCKSIZE | |
2006-07-08 19:39:58 +03:00
avctx - > frame_size > FLAC_MAX_BLOCKSIZE ) {
2006-07-02 13:22:31 +03:00
av_log ( avctx , AV_LOG_ERROR , " invalid block size: %d \n " ,
avctx - > frame_size ) ;
2012-12-31 14:13:36 +03:00
return AVERROR ( EINVAL ) ;
2006-07-02 13:22:31 +03:00
}
} else {
2008-03-31 03:29:52 +03:00
s - > avctx - > frame_size = select_blocksize ( s - > samplerate , s - > options . block_time_ms ) ;
2006-07-02 13:22:31 +03:00
}
2009-04-16 05:28:49 +03:00
s - > max_blocksize = s - > avctx - > frame_size ;
2006-07-02 13:22:31 +03:00
2006-06-26 09:00:07 +03:00
/* set maximum encoded frame size in verbatim mode */
2022-08-28 15:21:27 +02:00
s - > max_framesize = flac_get_max_frame_size ( s - > avctx - > frame_size ,
s - > channels ,
s - > avctx - > bits_per_raw_sample ) ;
2006-06-24 13:20:15 +03:00
2008-09-15 00:39:54 +03:00
/* initialize MD5 context */
2012-10-11 15:10:45 +03:00
s - > md5ctx = av_md5_alloc ( ) ;
2010-07-30 21:30:09 +03:00
if ( ! s - > md5ctx )
2010-04-03 17:15:00 +03:00
return AVERROR ( ENOMEM ) ;
2008-09-15 00:39:54 +03:00
av_md5_init ( s - > md5ctx ) ;
2006-06-24 13:20:15 +03:00
streaminfo = av_malloc ( FLAC_STREAMINFO_SIZE ) ;
2010-07-30 21:34:39 +03:00
if ( ! streaminfo )
return AVERROR ( ENOMEM ) ;
2006-06-24 13:20:15 +03:00
write_streaminfo ( s , streaminfo ) ;
avctx - > extradata = streaminfo ;
avctx - > extradata_size = FLAC_STREAMINFO_SIZE ;
2010-07-30 21:30:09 +03:00
s - > frame_count = 0 ;
2009-03-21 02:50:19 +02:00
s - > min_framesize = s - > max_framesize ;
2006-06-24 13:20:15 +03:00
2013-05-07 08:20:32 +03:00
if ( ( channels = = 3 & &
av_channel_layout_compare ( & avctx - > ch_layout , & ( AVChannelLayout ) AV_CHANNEL_LAYOUT_SURROUND ) ) | |
( channels = = 4 & &
av_channel_layout_compare ( & avctx - > ch_layout , & ( AVChannelLayout ) AV_CHANNEL_LAYOUT_2_2 ) & &
av_channel_layout_compare ( & avctx - > ch_layout , & ( AVChannelLayout ) AV_CHANNEL_LAYOUT_QUAD ) ) | |
( channels = = 5 & &
av_channel_layout_compare ( & avctx - > ch_layout , & ( AVChannelLayout ) AV_CHANNEL_LAYOUT_5POINT0 ) & &
av_channel_layout_compare ( & avctx - > ch_layout , & ( AVChannelLayout ) AV_CHANNEL_LAYOUT_5POINT0_BACK ) ) | |
( channels = = 6 & &
av_channel_layout_compare ( & avctx - > ch_layout , & ( AVChannelLayout ) AV_CHANNEL_LAYOUT_5POINT1 ) & &
av_channel_layout_compare ( & avctx - > ch_layout , & ( AVChannelLayout ) AV_CHANNEL_LAYOUT_5POINT1_BACK ) ) ) {
if ( avctx - > ch_layout . order ! = AV_CHANNEL_ORDER_UNSPEC ) {
2011-04-25 12:23:06 +03:00
av_log ( avctx , AV_LOG_ERROR , " Channel layout not supported by Flac, "
" output stream will have incorrect "
" channel layout. \n " ) ;
} else {
av_log ( avctx , AV_LOG_WARNING , " No channel layout specified. The encoder "
" will use Flac channel layout for "
" %d channels. \n " , channels ) ;
}
}
2011-01-21 02:12:03 +02:00
ret = ff_lpc_init ( & s - > lpc_ctx , avctx - > frame_size ,
2011-04-02 13:28:01 +03:00
s - > options . max_prediction_order , FF_LPC_TYPE_LEVINSON ) ;
2011-01-21 02:12:03 +02:00
2014-02-13 19:57:05 +03:00
ff_bswapdsp_init ( & s - > bdsp ) ;
2022-08-01 03:07:46 +02:00
ff_flacencdsp_init ( & s - > flac_dsp ) ;
2012-10-25 22:00:10 +03:00
2010-07-30 21:59:27 +03:00
dprint_compression_options ( s ) ;
2011-01-21 02:12:03 +02:00
return ret ;
2006-06-24 13:20:15 +03:00
}
2010-07-30 21:30:09 +03:00
2012-02-04 02:43:39 +03:00
static void init_frame ( FlacEncodeContext * s , int nb_samples )
2006-06-24 13:20:15 +03:00
{
int i , ch ;
FlacFrame * frame ;
frame = & s - > frame ;
2010-07-30 21:30:09 +03:00
for ( i = 0 ; i < 16 ; i + + ) {
2012-02-04 02:43:39 +03:00
if ( nb_samples = = ff_flac_blocksize_table [ i ] ) {
2010-07-30 21:30:09 +03:00
frame - > blocksize = ff_flac_blocksize_table [ i ] ;
2006-06-24 13:20:15 +03:00
frame - > bs_code [ 0 ] = i ;
frame - > bs_code [ 1 ] = 0 ;
break ;
}
}
2010-07-30 21:30:09 +03:00
if ( i = = 16 ) {
2012-02-04 02:43:39 +03:00
frame - > blocksize = nb_samples ;
2010-07-30 21:30:09 +03:00
if ( frame - > blocksize < = 256 ) {
2006-06-24 13:20:15 +03:00
frame - > bs_code [ 0 ] = 6 ;
frame - > bs_code [ 1 ] = frame - > blocksize - 1 ;
} else {
frame - > bs_code [ 0 ] = 7 ;
frame - > bs_code [ 1 ] = frame - > blocksize - 1 ;
}
}
2012-10-25 22:07:59 +03:00
for ( ch = 0 ; ch < s - > channels ; ch + + ) {
2012-10-27 07:46:43 +03:00
FlacSubframe * sub = & frame - > subframes [ ch ] ;
sub - > wasted = 0 ;
sub - > obits = s - > avctx - > bits_per_raw_sample ;
if ( sub - > obits > 16 )
sub - > rc . coding_mode = CODING_MODE_RICE2 ;
else
sub - > rc . coding_mode = CODING_MODE_RICE ;
2012-10-25 22:07:59 +03:00
}
2010-07-31 19:46:32 +03:00
frame - > verbatim_only = 0 ;
2006-06-24 13:20:15 +03:00
}
2010-07-30 21:30:09 +03:00
2006-06-24 13:20:15 +03:00
/**
2010-07-30 21:30:09 +03:00
* Copy channel - interleaved input samples into separate subframes .
2006-06-24 13:20:15 +03:00
*/
2012-10-27 07:26:02 +03:00
static void copy_samples ( FlacEncodeContext * s , const void * samples )
2006-06-24 13:20:15 +03:00
{
int i , j , ch ;
FlacFrame * frame ;
2012-10-27 07:26:02 +03:00
int shift = av_get_bytes_per_sample ( s - > avctx - > sample_fmt ) * 8 -
s - > avctx - > bits_per_raw_sample ;
# define COPY_SAMPLES(bits) do { \
const int # # bits # # _t * samples0 = samples ; \
frame = & s - > frame ; \
for ( i = 0 , j = 0 ; i < frame - > blocksize ; i + + ) \
for ( ch = 0 ; ch < s - > channels ; ch + + , j + + ) \
frame - > subframes [ ch ] . samples [ i ] = samples0 [ j ] > > shift ; \
} while ( 0 )
if ( s - > avctx - > sample_fmt = = AV_SAMPLE_FMT_S16 )
COPY_SAMPLES ( 16 ) ;
else
COPY_SAMPLES ( 32 ) ;
2006-06-24 13:20:15 +03:00
}
2006-06-28 00:01:21 +03:00
2015-05-19 19:47:22 +02:00
static uint64_t rice_count_exact ( const int32_t * res , int n , int k )
2010-07-31 23:32:12 +03:00
{
int i ;
2012-10-27 06:22:38 +03:00
uint64_t count = 0 ;
2010-07-31 23:32:12 +03:00
for ( i = 0 ; i < n ; i + + ) {
2022-10-11 19:24:36 +02:00
unsigned v = ( ( unsigned ) ( res [ i ] ) < < 1 ) ^ ( res [ i ] > > 31 ) ;
2010-07-31 23:32:12 +03:00
count + = ( v > > k ) + 1 + k ;
}
return count ;
}
2012-10-27 06:22:38 +03:00
static uint64_t subframe_count_exact ( FlacEncodeContext * s , FlacSubframe * sub ,
int pred_order )
2010-07-31 23:32:12 +03:00
{
int p , porder , psize ;
int i , part_end ;
2012-10-27 06:22:38 +03:00
uint64_t count = 0 ;
2010-07-31 23:32:12 +03:00
/* subframe header */
count + = 8 ;
2015-04-20 14:11:15 +02:00
if ( sub - > wasted )
count + = sub - > wasted ;
2010-07-31 23:32:12 +03:00
/* subframe */
if ( sub - > type = = FLAC_SUBFRAME_CONSTANT ) {
count + = sub - > obits ;
} else if ( sub - > type = = FLAC_SUBFRAME_VERBATIM ) {
count + = s - > frame . blocksize * sub - > obits ;
} else {
/* warm-up samples */
count + = pred_order * sub - > obits ;
/* LPC coefficients */
if ( sub - > type = = FLAC_SUBFRAME_LPC )
count + = 4 + 5 + pred_order * s - > options . lpc_coeff_precision ;
/* rice-encoded block */
count + = 2 ;
/* partition order */
porder = sub - > rc . porder ;
psize = s - > frame . blocksize > > porder ;
count + = 4 ;
/* residual */
i = pred_order ;
part_end = psize ;
for ( p = 0 ; p < 1 < < porder ; p + + ) {
int k = sub - > rc . params [ p ] ;
2012-10-27 07:46:43 +03:00
count + = sub - > rc . coding_mode ;
2010-07-31 23:32:12 +03:00
count + = rice_count_exact ( & sub - > residual [ i ] , part_end - i , k ) ;
i = part_end ;
part_end = FFMIN ( s - > frame . blocksize , part_end + psize ) ;
}
}
return count ;
}
2006-06-28 00:01:21 +03:00
# define rice_encode_count(sum, n, k) (((n)*((k)+1))+((sum-(n>>1))>>(k)))
2007-09-29 08:41:27 +03:00
/**
2010-07-30 21:30:09 +03:00
* Solve for d / dk ( rice_encode_count ) = n - ( ( sum - ( n > > 1 ) ) > > ( k + 1 ) ) = 0.
2007-09-29 08:41:27 +03:00
*/
2012-10-27 07:46:43 +03:00
static int find_optimal_param ( uint64_t sum , int n , int max_param )
2006-06-28 00:01:21 +03:00
{
2007-09-29 08:41:27 +03:00
int k ;
2012-10-27 06:22:38 +03:00
uint64_t sum2 ;
2007-09-29 08:41:27 +03:00
2010-07-30 21:30:09 +03:00
if ( sum < = n > > 1 )
2007-09-29 08:41:27 +03:00
return 0 ;
2010-07-30 21:30:09 +03:00
sum2 = sum - ( n > > 1 ) ;
2012-10-27 06:22:38 +03:00
k = av_log2 ( av_clipl_int32 ( sum2 / n ) ) ;
2012-10-27 07:46:43 +03:00
return FFMIN ( k , max_param ) ;
2006-06-28 00:01:21 +03:00
}
2015-05-19 13:26:55 +02:00
static int find_optimal_param_exact ( uint64_t sums [ 32 ] [ MAX_PARTITIONS ] , int i , int max_param )
{
int bestk = 0 ;
int64_t bestbits = INT64_MAX ;
int k ;
for ( k = 0 ; k < = max_param ; k + + ) {
int64_t bits = sums [ k ] [ i ] ;
if ( bits < bestbits ) {
bestbits = bits ;
bestk = k ;
}
}
return bestk ;
}
2010-07-30 21:30:09 +03:00
2012-10-27 06:22:38 +03:00
static uint64_t calc_optimal_rice_params ( RiceContext * rc , int porder ,
2015-05-19 13:26:55 +02:00
uint64_t sums [ 32 ] [ MAX_PARTITIONS ] ,
int n , int pred_order , int max_param , int exact )
2006-06-28 00:01:21 +03:00
{
int i ;
2015-05-19 13:26:55 +02:00
int k , cnt , part ;
2012-10-27 06:22:38 +03:00
uint64_t all_bits ;
2006-06-28 00:01:21 +03:00
2010-07-30 21:30:09 +03:00
part = ( 1 < < porder ) ;
2007-10-27 16:39:19 +03:00
all_bits = 4 * part ;
2006-06-28 00:01:21 +03:00
cnt = ( n > > porder ) - pred_order ;
2010-07-30 21:30:09 +03:00
for ( i = 0 ; i < part ; i + + ) {
2015-05-19 13:26:55 +02:00
if ( exact ) {
k = find_optimal_param_exact ( sums , i , max_param ) ;
all_bits + = sums [ k ] [ i ] ;
} else {
k = find_optimal_param ( sums [ 0 ] [ i ] , cnt , max_param ) ;
all_bits + = rice_encode_count ( sums [ 0 ] [ i ] , cnt , k ) ;
}
2006-06-28 00:01:21 +03:00
rc - > params [ i ] = k ;
2007-10-27 16:39:19 +03:00
cnt = n > > porder ;
2006-06-28 00:01:21 +03:00
}
rc - > porder = porder ;
return all_bits ;
}
2010-07-30 21:30:09 +03:00
2015-05-19 19:47:22 +02:00
static void calc_sum_top ( int pmax , int kmax , const uint32_t * data , int n , int pred_order ,
2015-05-19 13:26:55 +02:00
uint64_t sums [ 32 ] [ MAX_PARTITIONS ] )
2006-06-28 00:01:21 +03:00
{
2015-05-19 13:26:55 +02:00
int i , k ;
2006-07-02 12:30:51 +03:00
int parts ;
2015-05-19 19:47:22 +02:00
const uint32_t * res , * res_end ;
2006-06-28 00:01:21 +03:00
/* sums for highest level */
2010-07-30 21:30:09 +03:00
parts = ( 1 < < pmax ) ;
2015-05-19 13:26:55 +02:00
for ( k = 0 ; k < = kmax ; k + + ) {
res = & data [ pred_order ] ;
res_end = & data [ n > > pmax ] ;
for ( i = 0 ; i < parts ; i + + ) {
if ( kmax ) {
uint64_t sum = ( 1LL + k ) * ( res_end - res ) ;
while ( res < res_end )
sum + = * ( res + + ) > > k ;
sums [ k ] [ i ] = sum ;
} else {
uint64_t sum = 0 ;
while ( res < res_end )
sum + = * ( res + + ) ;
sums [ k ] [ i ] = sum ;
}
res_end + = n > > pmax ;
}
2006-06-28 00:01:21 +03:00
}
}
2015-05-19 13:26:55 +02:00
static void calc_sum_next ( int level , uint64_t sums [ 32 ] [ MAX_PARTITIONS ] , int kmax )
2014-11-22 21:05:08 +02:00
{
2015-05-19 13:26:55 +02:00
int i , k ;
2014-11-22 21:05:08 +02:00
int parts = ( 1 < < level ) ;
2015-05-19 13:26:55 +02:00
for ( i = 0 ; i < parts ; i + + ) {
for ( k = 0 ; k < = kmax ; k + + )
sums [ k ] [ i ] = sums [ k ] [ 2 * i ] + sums [ k ] [ 2 * i + 1 ] ;
}
2014-11-22 21:05:08 +02:00
}
2010-07-30 21:30:09 +03:00
2015-05-19 13:48:30 +02:00
static uint64_t calc_rice_params ( RiceContext * rc ,
uint32_t udata [ FLAC_MAX_BLOCKSIZE ] ,
uint64_t sums [ 32 ] [ MAX_PARTITIONS ] ,
int pmin , int pmax ,
2015-05-19 19:47:22 +02:00
const int32_t * data , int n , int pred_order , int exact )
2006-06-28 00:01:21 +03:00
{
int i ;
2012-10-27 06:22:38 +03:00
uint64_t bits [ MAX_PARTITION_ORDER + 1 ] ;
2006-06-28 00:01:21 +03:00
int opt_porder ;
2006-07-02 13:22:31 +03:00
RiceContext tmp_rc ;
2015-05-19 13:26:55 +02:00
int kmax = ( 1 < < rc - > coding_mode ) - 2 ;
2006-06-28 00:01:21 +03:00
2012-08-02 22:58:17 +03:00
av_assert1 ( pmin > = 0 & & pmin < = MAX_PARTITION_ORDER ) ;
av_assert1 ( pmax > = 0 & & pmax < = MAX_PARTITION_ORDER ) ;
av_assert1 ( pmin < = pmax ) ;
2006-06-28 00:01:21 +03:00
2012-10-27 07:46:43 +03:00
tmp_rc . coding_mode = rc - > coding_mode ;
2022-10-11 19:24:36 +02:00
for ( i = pred_order ; i < n ; i + + )
udata [ i ] = ( ( unsigned ) ( data [ i ] ) < < 1 ) ^ ( data [ i ] > > 31 ) ;
2006-06-28 00:01:21 +03:00
2015-05-19 13:48:30 +02:00
calc_sum_top ( pmax , exact ? kmax : 0 , udata , n , pred_order , sums ) ;
2006-06-28 00:01:21 +03:00
2006-07-02 13:22:31 +03:00
opt_porder = pmin ;
bits [ pmin ] = UINT32_MAX ;
2014-11-22 21:05:08 +02:00
for ( i = pmax ; ; ) {
2015-05-19 13:26:55 +02:00
bits [ i ] = calc_optimal_rice_params ( & tmp_rc , i , sums , n , pred_order , kmax , exact ) ;
2015-06-16 09:25:01 +02:00
if ( bits [ i ] < bits [ opt_porder ] | | pmax = = pmin ) {
2006-06-28 00:01:21 +03:00
opt_porder = i ;
2015-05-19 13:48:30 +02:00
* rc = tmp_rc ;
2006-06-28 00:01:21 +03:00
}
2014-11-22 21:05:08 +02:00
if ( i = = pmin )
break ;
2015-05-19 13:26:55 +02:00
calc_sum_next ( - - i , sums , exact ? kmax : 0 ) ;
2006-06-28 00:01:21 +03:00
}
2006-07-02 13:22:31 +03:00
return bits [ opt_porder ] ;
2006-06-28 00:01:21 +03:00
}
2010-07-30 21:30:09 +03:00
2006-07-03 12:20:26 +03:00
static int get_max_p_order ( int max_porder , int n , int order )
{
int porder = FFMIN ( max_porder , av_log2 ( n ^ ( n - 1 ) ) ) ;
2010-07-30 21:30:09 +03:00
if ( order > 0 )
2006-07-03 12:20:26 +03:00
porder = FFMIN ( porder , av_log2 ( n / order ) ) ;
return porder ;
}
2010-07-30 21:30:09 +03:00
2012-10-27 06:22:38 +03:00
static uint64_t find_subframe_rice_params ( FlacEncodeContext * s ,
2010-07-31 23:17:59 +03:00
FlacSubframe * sub , int pred_order )
2006-06-28 00:01:21 +03:00
{
2010-07-31 23:17:59 +03:00
int pmin = get_max_p_order ( s - > options . min_partition_order ,
s - > frame . blocksize , pred_order ) ;
int pmax = get_max_p_order ( s - > options . max_partition_order ,
s - > frame . blocksize , pred_order ) ;
2012-10-27 07:46:43 +03:00
uint64_t bits = 8 + pred_order * sub - > obits + 2 + sub - > rc . coding_mode ;
2010-07-31 23:17:59 +03:00
if ( sub - > type = = FLAC_SUBFRAME_LPC )
bits + = 4 + 5 + pred_order * s - > options . lpc_coeff_precision ;
2015-05-19 13:48:30 +02:00
bits + = calc_rice_params ( & sub - > rc , sub - > rc_udata , sub - > rc_sums , pmin , pmax , sub - > residual ,
2015-05-19 13:26:55 +02:00
s - > frame . blocksize , pred_order , s - > options . exact_rice_parameters ) ;
2006-06-28 00:01:21 +03:00
return bits ;
}
2010-07-30 21:30:09 +03:00
2006-07-02 13:22:31 +03:00
static void encode_residual_fixed ( int32_t * res , const int32_t * smp , int n ,
int order )
2006-06-28 00:01:21 +03:00
{
int i ;
2010-07-30 21:30:09 +03:00
for ( i = 0 ; i < order ; i + + )
2006-06-28 00:01:21 +03:00
res [ i ] = smp [ i ] ;
2010-07-30 21:30:09 +03:00
if ( order = = 0 ) {
for ( i = order ; i < n ; i + + )
res [ i ] = smp [ i ] ;
} else if ( order = = 1 ) {
for ( i = order ; i < n ; i + + )
res [ i ] = smp [ i ] - smp [ i - 1 ] ;
} else if ( order = = 2 ) {
2007-09-30 02:21:57 +03:00
int a = smp [ order - 1 ] - smp [ order - 2 ] ;
2010-07-30 21:30:09 +03:00
for ( i = order ; i < n ; i + = 2 ) {
int b = smp [ i ] - smp [ i - 1 ] ;
res [ i ] = b - a ;
a = smp [ i + 1 ] - smp [ i ] ;
res [ i + 1 ] = a - b ;
2007-09-30 02:21:57 +03:00
}
2010-07-30 21:30:09 +03:00
} else if ( order = = 3 ) {
int a = smp [ order - 1 ] - smp [ order - 2 ] ;
2007-09-30 02:21:57 +03:00
int c = smp [ order - 1 ] - 2 * smp [ order - 2 ] + smp [ order - 3 ] ;
2010-07-30 21:30:09 +03:00
for ( i = order ; i < n ; i + = 2 ) {
int b = smp [ i ] - smp [ i - 1 ] ;
int d = b - a ;
res [ i ] = d - c ;
a = smp [ i + 1 ] - smp [ i ] ;
c = a - b ;
res [ i + 1 ] = c - d ;
2007-09-30 02:21:57 +03:00
}
2010-07-30 21:30:09 +03:00
} else {
int a = smp [ order - 1 ] - smp [ order - 2 ] ;
int c = smp [ order - 1 ] - 2 * smp [ order - 2 ] + smp [ order - 3 ] ;
2007-09-30 02:21:57 +03:00
int e = smp [ order - 1 ] - 3 * smp [ order - 2 ] + 3 * smp [ order - 3 ] - smp [ order - 4 ] ;
2010-07-30 21:30:09 +03:00
for ( i = order ; i < n ; i + = 2 ) {
int b = smp [ i ] - smp [ i - 1 ] ;
int d = b - a ;
int f = d - c ;
res [ i ] = f - e ;
a = smp [ i + 1 ] - smp [ i ] ;
c = a - b ;
e = c - d ;
res [ i + 1 ] = e - f ;
2007-09-30 02:21:57 +03:00
}
2006-06-28 00:01:21 +03:00
}
}
2010-07-30 21:30:09 +03:00
2022-10-11 19:24:36 +02:00
/* These four functions check for every residual whether it can be
* contained in < INT32_MIN , INT32_MAX ] . In case it doesn ' t , the
* function that called this function has to try something else .
* Each function is duplicated , once for int32_t input , once for
* int64_t input */
# define ENCODE_RESIDUAL_FIXED_WITH_RESIDUAL_LIMIT() \
{ \
for ( int i = 0 ; i < order ; i + + ) \
res [ i ] = smp [ i ] ; \
if ( order = = 0 ) { \
for ( int i = order ; i < n ; i + + ) { \
if ( smp [ i ] = = INT32_MIN ) \
return 1 ; \
res [ i ] = smp [ i ] ; \
} \
} else if ( order = = 1 ) { \
for ( int i = order ; i < n ; i + + ) { \
int64_t res64 = ( int64_t ) smp [ i ] - smp [ i - 1 ] ; \
if ( res64 < = INT32_MIN | | res64 > INT32_MAX ) \
return 1 ; \
res [ i ] = res64 ; \
} \
} else if ( order = = 2 ) { \
for ( int i = order ; i < n ; i + + ) { \
int64_t res64 = ( int64_t ) smp [ i ] - 2 * ( int64_t ) smp [ i - 1 ] + smp [ i - 2 ] ; \
if ( res64 < = INT32_MIN | | res64 > INT32_MAX ) \
return 1 ; \
res [ i ] = res64 ; \
} \
} else if ( order = = 3 ) { \
for ( int i = order ; i < n ; i + + ) { \
int64_t res64 = ( int64_t ) smp [ i ] - 3 * ( int64_t ) smp [ i - 1 ] + 3 * ( int64_t ) smp [ i - 2 ] - smp [ i - 3 ] ; \
if ( res64 < = INT32_MIN | | res64 > INT32_MAX ) \
return 1 ; \
res [ i ] = res64 ; \
} \
} else { \
for ( int i = order ; i < n ; i + + ) { \
int64_t res64 = ( int64_t ) smp [ i ] - 4 * ( int64_t ) smp [ i - 1 ] + 6 * ( int64_t ) smp [ i - 2 ] - 4 * ( int64_t ) smp [ i - 3 ] + smp [ i - 4 ] ; \
if ( res64 < = INT32_MIN | | res64 > INT32_MAX ) \
return 1 ; \
res [ i ] = res64 ; \
} \
} \
return 0 ; \
}
static int encode_residual_fixed_with_residual_limit ( int32_t * res , const int32_t * smp ,
int n , int order )
{
ENCODE_RESIDUAL_FIXED_WITH_RESIDUAL_LIMIT ( ) ;
}
static int encode_residual_fixed_with_residual_limit_33bps ( int32_t * res , const int64_t * smp ,
int n , int order )
{
ENCODE_RESIDUAL_FIXED_WITH_RESIDUAL_LIMIT ( ) ;
}
# define LPC_ENCODE_WITH_RESIDUAL_LIMIT() \
{ \
for ( int i = 0 ; i < order ; i + + ) \
res [ i ] = smp [ i ] ; \
for ( int i = order ; i < len ; i + + ) { \
int64_t p = 0 , tmp ; \
for ( int j = 0 ; j < order ; j + + ) \
p + = ( int64_t ) coefs [ j ] * smp [ ( i - 1 ) - j ] ; \
p > > = shift ; \
tmp = smp [ i ] - p ; \
if ( tmp < = INT32_MIN | | tmp > INT32_MAX ) \
return 1 ; \
res [ i ] = tmp ; \
} \
return 0 ; \
}
static int lpc_encode_with_residual_limit ( int32_t * res , const int32_t * smp , int len ,
int order , int32_t * coefs , int shift )
{
LPC_ENCODE_WITH_RESIDUAL_LIMIT ( ) ;
}
static int lpc_encode_with_residual_limit_33bps ( int32_t * res , const int64_t * smp , int len ,
int order , int32_t * coefs , int shift )
{
LPC_ENCODE_WITH_RESIDUAL_LIMIT ( ) ;
}
static int lpc_encode_choose_datapath ( FlacEncodeContext * s , int32_t bps ,
int32_t * res , const int32_t * smp ,
const int64_t * smp_33bps , int len ,
int order , int32_t * coefs , int shift )
{
uint64_t max_residual_value = 0 ;
int64_t max_sample_value = ( ( int64_t ) ( 1 ) < < ( bps - 1 ) ) ;
/* This calculates the max size of any residual with the current
* predictor , so we know whether we need to check the residual */
for ( int i = 0 ; i < order ; i + + )
max_residual_value + = FFABS ( max_sample_value * coefs [ i ] ) ;
max_residual_value > > = shift ;
max_residual_value + = max_sample_value ;
if ( bps > 32 ) {
if ( lpc_encode_with_residual_limit_33bps ( res , smp_33bps , len , order , coefs , shift ) )
return 1 ;
} else if ( max_residual_value > INT32_MAX ) {
if ( lpc_encode_with_residual_limit ( res , smp , len , order , coefs , shift ) )
return 1 ;
} else if ( bps + s - > options . lpc_coeff_precision + av_log2 ( order ) < = 32 ) {
s - > flac_dsp . lpc16_encode ( res , smp , len , order , coefs , shift ) ;
} else {
s - > flac_dsp . lpc32_encode ( res , smp , len , order , coefs , shift ) ;
}
return 0 ;
}
# define DEFAULT_TO_VERBATIM() \
{ \
sub - > type = sub - > type_code = FLAC_SUBFRAME_VERBATIM ; \
if ( sub - > obits < = 32 ) \
memcpy ( res , smp , n * sizeof ( int32_t ) ) ; \
return subframe_count_exact ( s , sub , 0 ) ; \
}
2010-07-31 19:37:23 +03:00
static int encode_residual_ch ( FlacEncodeContext * s , int ch )
2006-06-28 00:01:21 +03:00
{
2006-07-02 13:22:31 +03:00
int i , n ;
2010-07-31 23:17:59 +03:00
int min_order , max_order , opt_order , omethod ;
2006-06-28 00:01:21 +03:00
FlacFrame * frame ;
FlacSubframe * sub ;
2006-07-02 13:22:31 +03:00
int32_t coefs [ MAX_LPC_ORDER ] [ MAX_LPC_ORDER ] ;
int shift [ MAX_LPC_ORDER ] ;
2006-06-28 00:01:21 +03:00
int32_t * res , * smp ;
2022-10-11 19:24:36 +02:00
int64_t * smp_33bps ;
2006-06-28 00:01:21 +03:00
2022-10-11 19:24:36 +02:00
frame = & s - > frame ;
sub = & frame - > subframes [ ch ] ;
res = sub - > residual ;
smp = sub - > samples ;
smp_33bps = frame - > samples_33bps ;
n = frame - > blocksize ;
2006-06-28 00:01:21 +03:00
/* CONSTANT */
2022-10-11 19:24:36 +02:00
if ( sub - > obits > 32 ) {
for ( i = 1 ; i < n ; i + + )
if ( smp_33bps [ i ] ! = smp_33bps [ 0 ] )
break ;
if ( i = = n ) {
sub - > type = sub - > type_code = FLAC_SUBFRAME_CONSTANT ;
return subframe_count_exact ( s , sub , 0 ) ;
}
} else {
for ( i = 1 ; i < n ; i + + )
if ( smp [ i ] ! = smp [ 0 ] )
break ;
if ( i = = n ) {
sub - > type = sub - > type_code = FLAC_SUBFRAME_CONSTANT ;
res [ 0 ] = smp [ 0 ] ;
return subframe_count_exact ( s , sub , 0 ) ;
}
2006-06-28 00:01:21 +03:00
}
/* VERBATIM */
2010-07-31 19:46:32 +03:00
if ( frame - > verbatim_only | | n < 5 ) {
2022-10-11 19:24:36 +02:00
DEFAULT_TO_VERBATIM ( ) ;
2006-06-28 00:01:21 +03:00
}
2010-07-30 22:40:18 +03:00
min_order = s - > options . min_prediction_order ;
max_order = s - > options . max_prediction_order ;
omethod = s - > options . prediction_order_method ;
2006-06-28 00:01:21 +03:00
/* FIXED */
2010-07-31 23:17:59 +03:00
sub - > type = FLAC_SUBFRAME_FIXED ;
2011-04-02 13:28:01 +03:00
if ( s - > options . lpc_type = = FF_LPC_TYPE_NONE | |
s - > options . lpc_type = = FF_LPC_TYPE_FIXED | | n < = max_order ) {
2012-10-27 06:22:38 +03:00
uint64_t bits [ MAX_FIXED_ORDER + 1 ] ;
2010-07-30 21:30:09 +03:00
if ( max_order > MAX_FIXED_ORDER )
max_order = MAX_FIXED_ORDER ;
2006-07-02 13:22:31 +03:00
opt_order = 0 ;
2010-07-30 21:30:09 +03:00
bits [ 0 ] = UINT32_MAX ;
for ( i = min_order ; i < = max_order ; i + + ) {
2022-10-11 19:24:36 +02:00
if ( sub - > obits = = 33 ) {
if ( encode_residual_fixed_with_residual_limit_33bps ( res , smp_33bps , n , i ) )
continue ;
} else if ( sub - > obits + i > = 32 ) {
if ( encode_residual_fixed_with_residual_limit ( res , smp , n , i ) )
continue ;
} else
encode_residual_fixed ( res , smp , n , i ) ;
2010-07-31 23:19:07 +03:00
bits [ i ] = find_subframe_rice_params ( s , sub , i ) ;
2010-07-30 21:30:09 +03:00
if ( bits [ i ] < bits [ opt_order ] )
2006-07-02 13:22:31 +03:00
opt_order = i ;
2006-06-28 00:01:21 +03:00
}
2022-10-11 19:24:36 +02:00
if ( opt_order = = 0 & & bits [ 0 ] = = UINT32_MAX ) {
/* No predictor found with residuals within <INT32_MIN,INT32_MAX],
* so encode a verbatim subframe instead */
DEFAULT_TO_VERBATIM ( ) ;
}
2010-07-30 21:30:09 +03:00
sub - > order = opt_order ;
2006-07-02 13:22:31 +03:00
sub - > type_code = sub - > type | sub - > order ;
2010-07-30 21:30:09 +03:00
if ( sub - > order ! = max_order ) {
2022-10-11 19:24:36 +02:00
if ( sub - > obits = = 33 )
encode_residual_fixed_with_residual_limit_33bps ( res , smp_33bps , n , sub - > order ) ;
else if ( sub - > obits + i > = 32 )
encode_residual_fixed_with_residual_limit ( res , smp , n , sub - > order ) ;
else
encode_residual_fixed ( res , smp , n , sub - > order ) ;
2010-07-31 23:32:12 +03:00
find_subframe_rice_params ( s , sub , sub - > order ) ;
2006-07-02 13:22:31 +03:00
}
2010-07-31 23:32:12 +03:00
return subframe_count_exact ( s , sub , sub - > order ) ;
2006-06-28 00:01:21 +03:00
}
2006-07-02 13:22:31 +03:00
/* LPC */
2010-07-31 23:17:59 +03:00
sub - > type = FLAC_SUBFRAME_LPC ;
2022-10-11 19:24:36 +02:00
if ( sub - > obits = = 33 )
/* As ff_lpc_calc_coefs is shared with other codecs and the LSB
* probably isn ' t predictable anyway , throw away LSB for analysis
* so it fits 32 bit int and existing function can be used
* unmodified */
for ( i = 0 ; i < n ; i + + )
smp [ i ] = smp_33bps [ i ] > > 1 ;
2011-01-21 02:11:44 +02:00
opt_order = ff_lpc_calc_coefs ( & s - > lpc_ctx , smp , n , min_order , max_order ,
2010-07-31 23:17:59 +03:00
s - > options . lpc_coeff_precision , coefs , shift , s - > options . lpc_type ,
2010-07-30 22:40:18 +03:00
s - > options . lpc_passes , omethod ,
2016-08-22 23:02:04 +02:00
MIN_LPC_SHIFT , MAX_LPC_SHIFT , 0 ) ;
2006-07-16 16:34:47 +03:00
2010-07-30 21:30:09 +03:00
if ( omethod = = ORDER_METHOD_2LEVEL | |
omethod = = ORDER_METHOD_4LEVEL | |
omethod = = ORDER_METHOD_8LEVEL ) {
2006-07-16 16:34:47 +03:00
int levels = 1 < < omethod ;
2012-10-27 06:22:38 +03:00
uint64_t bits [ 1 < < ORDER_METHOD_8LEVEL ] ;
2012-11-07 22:48:28 +03:00
int order = - 1 ;
2010-07-30 21:30:09 +03:00
int opt_index = levels - 1 ;
opt_order = max_order - 1 ;
2006-07-16 16:34:47 +03:00
bits [ opt_index ] = UINT32_MAX ;
2010-07-30 21:30:09 +03:00
for ( i = levels - 1 ; i > = 0 ; i - - ) {
2012-11-07 22:48:28 +03:00
int last_order = order ;
2006-07-16 16:34:47 +03:00
order = min_order + ( ( ( max_order - min_order + 1 ) * ( i + 1 ) ) / levels ) - 1 ;
2012-11-07 22:48:28 +03:00
order = av_clip ( order , min_order - 1 , max_order - 1 ) ;
if ( order = = last_order )
continue ;
2022-10-11 19:24:36 +02:00
if ( lpc_encode_choose_datapath ( s , sub - > obits , res , smp , smp_33bps , n , order + 1 , coefs [ order ] , shift [ order ] ) )
continue ;
2010-07-31 23:19:07 +03:00
bits [ i ] = find_subframe_rice_params ( s , sub , order + 1 ) ;
2010-07-30 21:30:09 +03:00
if ( bits [ i ] < bits [ opt_index ] ) {
2006-07-16 16:34:47 +03:00
opt_index = i ;
opt_order = order ;
}
}
opt_order + + ;
2010-07-30 21:30:09 +03:00
} else if ( omethod = = ORDER_METHOD_SEARCH ) {
2006-07-16 16:34:47 +03:00
// brute-force optimal order search
2012-10-27 06:22:38 +03:00
uint64_t bits [ MAX_LPC_ORDER ] ;
2006-07-16 16:34:47 +03:00
opt_order = 0 ;
2010-07-30 21:30:09 +03:00
bits [ 0 ] = UINT32_MAX ;
for ( i = min_order - 1 ; i < max_order ; i + + ) {
2022-10-11 19:24:36 +02:00
if ( lpc_encode_choose_datapath ( s , sub - > obits , res , smp , smp_33bps , n , i + 1 , coefs [ i ] , shift [ i ] ) )
continue ;
2010-07-31 23:19:07 +03:00
bits [ i ] = find_subframe_rice_params ( s , sub , i + 1 ) ;
2010-07-30 21:30:09 +03:00
if ( bits [ i ] < bits [ opt_order ] )
2006-07-16 16:34:47 +03:00
opt_order = i ;
}
opt_order + + ;
2010-07-30 21:30:09 +03:00
} else if ( omethod = = ORDER_METHOD_LOG ) {
2012-10-27 06:22:38 +03:00
uint64_t bits [ MAX_LPC_ORDER ] ;
2006-07-16 18:46:45 +03:00
int step ;
2010-07-30 21:30:09 +03:00
opt_order = min_order - 1 + ( max_order - min_order ) / 3 ;
2006-07-16 18:46:45 +03:00
memset ( bits , - 1 , sizeof ( bits ) ) ;
2010-07-30 21:30:09 +03:00
for ( step = 16 ; step ; step > > = 1 ) {
int last = opt_order ;
for ( i = last - step ; i < = last + step ; i + = step ) {
if ( i < min_order - 1 | | i > = max_order | | bits [ i ] < UINT32_MAX )
2006-07-16 18:46:45 +03:00
continue ;
2022-10-11 19:24:36 +02:00
if ( lpc_encode_choose_datapath ( s , sub - > obits , res , smp , smp_33bps , n , i + 1 , coefs [ i ] , shift [ i ] ) )
continue ;
2010-07-31 23:19:07 +03:00
bits [ i ] = find_subframe_rice_params ( s , sub , i + 1 ) ;
2010-07-30 21:30:09 +03:00
if ( bits [ i ] < bits [ opt_order ] )
opt_order = i ;
2006-07-16 18:46:45 +03:00
}
}
opt_order + + ;
2006-07-16 16:34:47 +03:00
}
2015-05-20 01:23:39 +02:00
if ( s - > options . multi_dim_quant ) {
int allsteps = 1 ;
int i , step , improved ;
int64_t best_score = INT64_MAX ;
int32_t qmax ;
qmax = ( 1 < < ( s - > options . lpc_coeff_precision - 1 ) ) - 1 ;
for ( i = 0 ; i < opt_order ; i + + )
allsteps * = 3 ;
do {
improved = 0 ;
for ( step = 0 ; step < allsteps ; step + + ) {
int tmp = step ;
int32_t lpc_try [ MAX_LPC_ORDER ] ;
int64_t score = 0 ;
int diffsum = 0 ;
for ( i = 0 ; i < opt_order ; i + + ) {
int diff = ( ( tmp + 1 ) % 3 ) - 1 ;
lpc_try [ i ] = av_clip ( coefs [ opt_order - 1 ] [ i ] + diff , - qmax , qmax ) ;
tmp / = 3 ;
diffsum + = ! ! diff ;
}
if ( diffsum > 8 )
continue ;
2022-10-11 19:24:36 +02:00
if ( lpc_encode_choose_datapath ( s , sub - > obits , res , smp , smp_33bps , n , opt_order , lpc_try , shift [ opt_order - 1 ] ) )
continue ;
2015-05-20 01:23:39 +02:00
score = find_subframe_rice_params ( s , sub , opt_order ) ;
if ( score < best_score ) {
best_score = score ;
2015-06-02 15:41:44 +02:00
memcpy ( coefs [ opt_order - 1 ] , lpc_try , sizeof ( * coefs ) ) ;
2015-05-20 01:23:39 +02:00
improved = 1 ;
}
}
} while ( improved ) ;
}
2010-07-30 21:30:09 +03:00
sub - > order = opt_order ;
2006-07-02 13:22:31 +03:00
sub - > type_code = sub - > type | ( sub - > order - 1 ) ;
2010-07-30 21:30:09 +03:00
sub - > shift = shift [ sub - > order - 1 ] ;
for ( i = 0 ; i < sub - > order ; i + + )
2006-07-02 13:22:31 +03:00
sub - > coefs [ i ] = coefs [ sub - > order - 1 ] [ i ] ;
2010-07-30 21:30:09 +03:00
2022-10-11 19:24:36 +02:00
if ( lpc_encode_choose_datapath ( s , sub - > obits , res , smp , smp_33bps , n , sub - > order , sub - > coefs , sub - > shift ) ) {
/* No predictor found with residuals within <INT32_MIN,INT32_MAX],
* so encode a verbatim subframe instead */
DEFAULT_TO_VERBATIM ( ) ;
2015-05-12 13:00:29 +02:00
}
2010-07-30 21:30:09 +03:00
2010-07-31 23:32:12 +03:00
find_subframe_rice_params ( s , sub , sub - > order ) ;
return subframe_count_exact ( s , sub , sub - > order ) ;
2006-06-28 00:01:21 +03:00
}
2010-07-30 21:30:09 +03:00
2010-07-31 19:37:23 +03:00
static int count_frame_header ( FlacEncodeContext * s )
{
2011-06-03 14:52:29 +03:00
uint8_t av_unused tmp ;
2010-07-31 19:37:23 +03:00
int count ;
/*
< 14 > Sync code
< 1 > Reserved
< 1 > Blocking strategy
< 4 > Block size in inter - channel samples
< 4 > Sample rate
< 4 > Channel assignment
< 3 > Sample size in bits
< 1 > Reserved
*/
count = 32 ;
/* coded frame number */
PUT_UTF8 ( s - > frame_count , tmp , count + = 8 ; )
/* explicit block size */
2010-07-31 21:48:48 +03:00
if ( s - > frame . bs_code [ 0 ] = = 6 )
count + = 8 ;
else if ( s - > frame . bs_code [ 0 ] = = 7 )
count + = 16 ;
2010-07-31 19:37:23 +03:00
/* explicit sample rate */
2016-01-24 21:47:49 +02:00
count + = ( ( s - > sr_code [ 0 ] = = 12 ) + ( s - > sr_code [ 0 ] > 12 ) * 2 ) * 8 ;
2010-07-31 19:37:23 +03:00
/* frame header CRC-8 */
count + = 8 ;
return count ;
}
static int encode_frame ( FlacEncodeContext * s )
{
2012-10-27 06:22:38 +03:00
int ch ;
uint64_t count ;
2010-07-31 19:37:23 +03:00
count = count_frame_header ( s ) ;
for ( ch = 0 ; ch < s - > channels ; ch + + )
count + = encode_residual_ch ( s , ch ) ;
count + = ( 8 - ( count & 7 ) ) & 7 ; // byte alignment
count + = 16 ; // CRC-16
2012-10-27 06:22:38 +03:00
count > > = 3 ;
if ( count > INT_MAX )
return AVERROR_BUG ;
return count ;
2010-07-31 19:37:23 +03:00
}
2012-10-25 22:07:59 +03:00
static void remove_wasted_bits ( FlacEncodeContext * s )
{
2022-10-11 19:24:36 +02:00
int ch , i , wasted_bits ;
2012-10-25 22:07:59 +03:00
for ( ch = 0 ; ch < s - > channels ; ch + + ) {
FlacSubframe * sub = & s - > frame . subframes [ ch ] ;
2022-10-11 19:24:36 +02:00
if ( sub - > obits > 32 ) {
int64_t v = 0 ;
for ( i = 0 ; i < s - > frame . blocksize ; i + + ) {
v | = s - > frame . samples_33bps [ i ] ;
if ( v & 1 )
break ;
}
if ( ! v | | ( v & 1 ) )
return ;
v = ff_ctzll ( v ) ;
/* If any wasted bits are found, samples are moved
* from frame . samples_33bps to frame . subframes [ ch ] */
for ( i = 0 ; i < s - > frame . blocksize ; i + + )
sub - > samples [ i ] = s - > frame . samples_33bps [ i ] > > v ;
wasted_bits = v ;
} else {
int32_t v = 0 ;
for ( i = 0 ; i < s - > frame . blocksize ; i + + ) {
v | = sub - > samples [ i ] ;
if ( v & 1 )
break ;
}
if ( ! v | | ( v & 1 ) )
return ;
2012-10-25 22:07:59 +03:00
2015-10-11 23:43:29 +02:00
v = ff_ctz ( v ) ;
2012-10-25 22:07:59 +03:00
for ( i = 0 ; i < s - > frame . blocksize ; i + + )
sub - > samples [ i ] > > = v ;
2022-10-11 19:24:36 +02:00
wasted_bits = v ;
}
2012-10-25 22:07:59 +03:00
2022-10-11 19:24:36 +02:00
sub - > wasted = wasted_bits ;
sub - > obits - = wasted_bits ;
2012-10-27 07:46:43 +03:00
2022-10-11 19:24:36 +02:00
/* for 24-bit, check if removing wasted bits makes the range better
* suited for using RICE instead of RICE2 for entropy coding */
if ( sub - > obits < = 17 )
sub - > rc . coding_mode = CODING_MODE_RICE ;
2012-10-25 22:07:59 +03:00
}
2010-07-31 19:37:23 +03:00
}
2015-05-19 19:47:22 +02:00
static int estimate_stereo_mode ( const int32_t * left_ch , const int32_t * right_ch , int n ,
2022-10-11 19:24:36 +02:00
int max_rice_param , int bps )
2006-06-26 09:00:07 +03:00
{
2022-10-11 19:24:36 +02:00
int best ;
2006-06-28 00:01:21 +03:00
uint64_t sum [ 4 ] ;
2006-06-26 09:00:07 +03:00
uint64_t score [ 4 ] ;
2006-06-28 00:01:21 +03:00
int k ;
2006-06-26 09:00:07 +03:00
2006-07-02 13:22:31 +03:00
/* calculate sum of 2nd order residual for each channel */
2006-06-28 00:01:21 +03:00
sum [ 0 ] = sum [ 1 ] = sum [ 2 ] = sum [ 3 ] = 0 ;
2022-10-11 19:24:36 +02:00
if ( bps < 30 ) {
int32_t lt , rt ;
for ( int i = 2 ; i < n ; i + + ) {
lt = left_ch [ i ] - 2 * left_ch [ i - 1 ] + left_ch [ i - 2 ] ;
rt = right_ch [ i ] - 2 * right_ch [ i - 1 ] + right_ch [ i - 2 ] ;
sum [ 2 ] + = FFABS ( ( lt + rt ) > > 1 ) ;
sum [ 3 ] + = FFABS ( lt - rt ) ;
sum [ 0 ] + = FFABS ( lt ) ;
sum [ 1 ] + = FFABS ( rt ) ;
}
} else {
int64_t lt , rt ;
for ( int i = 2 ; i < n ; i + + ) {
lt = ( int64_t ) left_ch [ i ] - 2 * ( int64_t ) left_ch [ i - 1 ] + left_ch [ i - 2 ] ;
rt = ( int64_t ) right_ch [ i ] - 2 * ( int64_t ) right_ch [ i - 1 ] + right_ch [ i - 2 ] ;
sum [ 2 ] + = FFABS ( ( lt + rt ) > > 1 ) ;
sum [ 3 ] + = FFABS ( lt - rt ) ;
sum [ 0 ] + = FFABS ( lt ) ;
sum [ 1 ] + = FFABS ( rt ) ;
}
2006-06-28 00:01:21 +03:00
}
2006-07-02 13:22:31 +03:00
/* estimate bit counts */
2022-10-11 19:24:36 +02:00
for ( int i = 0 ; i < 4 ; i + + ) {
2012-10-27 07:46:43 +03:00
k = find_optimal_param ( 2 * sum [ i ] , n , max_rice_param ) ;
2010-07-30 21:30:09 +03:00
sum [ i ] = rice_encode_count ( 2 * sum [ i ] , n , k ) ;
2006-06-26 09:00:07 +03:00
}
/* calculate score for each mode */
2006-06-28 00:01:21 +03:00
score [ 0 ] = sum [ 0 ] + sum [ 1 ] ;
score [ 1 ] = sum [ 0 ] + sum [ 3 ] ;
score [ 2 ] = sum [ 1 ] + sum [ 3 ] ;
score [ 3 ] = sum [ 2 ] + sum [ 3 ] ;
2006-06-26 09:00:07 +03:00
/* return mode with lowest score */
best = 0 ;
2022-10-11 19:24:36 +02:00
for ( int i = 1 ; i < 4 ; i + + )
2010-07-30 21:30:09 +03:00
if ( score [ i ] < score [ best ] )
2006-06-26 09:00:07 +03:00
best = i ;
2012-06-17 13:45:10 +03:00
return best ;
2006-06-26 09:00:07 +03:00
}
2010-07-30 21:30:09 +03:00
2006-06-26 09:00:07 +03:00
/**
2010-07-30 21:30:09 +03:00
* Perform stereo channel decorrelation .
2006-06-26 09:00:07 +03:00
*/
2010-07-30 22:40:18 +03:00
static void channel_decorrelation ( FlacEncodeContext * s )
2006-06-26 09:00:07 +03:00
{
FlacFrame * frame ;
int32_t * left , * right ;
2022-10-11 19:24:36 +02:00
int64_t * side_33bps ;
int n ;
2006-06-26 09:00:07 +03:00
2022-10-11 19:24:36 +02:00
frame = & s - > frame ;
n = frame - > blocksize ;
left = frame - > subframes [ 0 ] . samples ;
right = frame - > subframes [ 1 ] . samples ;
side_33bps = frame - > samples_33bps ;
2006-06-26 09:00:07 +03:00
2010-07-30 22:40:18 +03:00
if ( s - > channels ! = 2 ) {
2009-03-21 02:44:42 +02:00
frame - > ch_mode = FLAC_CHMODE_INDEPENDENT ;
2006-06-26 09:00:07 +03:00
return ;
}
2012-10-27 07:46:43 +03:00
if ( s - > options . ch_mode < 0 ) {
int max_rice_param = ( 1 < < frame - > subframes [ 0 ] . rc . coding_mode ) - 2 ;
2022-10-11 19:24:36 +02:00
frame - > ch_mode = estimate_stereo_mode ( left , right , n , max_rice_param , s - > avctx - > bits_per_raw_sample ) ;
2012-10-27 07:46:43 +03:00
} else
2012-07-02 16:52:05 +03:00
frame - > ch_mode = s - > options . ch_mode ;
2006-06-26 09:00:07 +03:00
/* perform decorrelation and adjust bits-per-sample */
2010-07-30 21:30:09 +03:00
if ( frame - > ch_mode = = FLAC_CHMODE_INDEPENDENT )
2006-06-26 09:00:07 +03:00
return ;
2022-10-11 19:24:36 +02:00
if ( s - > avctx - > bits_per_raw_sample = = 32 ) {
if ( frame - > ch_mode = = FLAC_CHMODE_MID_SIDE ) {
int64_t tmp ;
for ( int i = 0 ; i < n ; i + + ) {
tmp = left [ i ] ;
left [ i ] = ( tmp + right [ i ] ) > > 1 ;
side_33bps [ i ] = tmp - right [ i ] ;
}
frame - > subframes [ 1 ] . obits + + ;
} else if ( frame - > ch_mode = = FLAC_CHMODE_LEFT_SIDE ) {
for ( int i = 0 ; i < n ; i + + )
side_33bps [ i ] = ( int64_t ) left [ i ] - right [ i ] ;
frame - > subframes [ 1 ] . obits + + ;
} else {
for ( int i = 0 ; i < n ; i + + )
side_33bps [ i ] = ( int64_t ) left [ i ] - right [ i ] ;
frame - > subframes [ 0 ] . obits + + ;
2006-06-26 09:00:07 +03:00
}
} else {
2022-10-11 19:24:36 +02:00
if ( frame - > ch_mode = = FLAC_CHMODE_MID_SIDE ) {
int32_t tmp ;
for ( int i = 0 ; i < n ; i + + ) {
tmp = left [ i ] ;
left [ i ] = ( tmp + right [ i ] ) > > 1 ;
right [ i ] = tmp - right [ i ] ;
}
frame - > subframes [ 1 ] . obits + + ;
} else if ( frame - > ch_mode = = FLAC_CHMODE_LEFT_SIDE ) {
for ( int i = 0 ; i < n ; i + + )
right [ i ] = left [ i ] - right [ i ] ;
frame - > subframes [ 1 ] . obits + + ;
} else {
for ( int i = 0 ; i < n ; i + + )
left [ i ] - = right [ i ] ;
frame - > subframes [ 0 ] . obits + + ;
}
2006-06-26 09:00:07 +03:00
}
}
2010-07-30 21:30:09 +03:00
2006-06-28 00:01:21 +03:00
static void write_utf8 ( PutBitContext * pb , uint32_t val )
2006-06-24 13:20:15 +03:00
{
2006-11-06 12:32:48 +02:00
uint8_t tmp ;
PUT_UTF8 ( val , tmp , put_bits ( pb , 8 , tmp ) ; )
2006-06-24 13:20:15 +03:00
}
2010-07-30 21:30:09 +03:00
2010-08-01 00:14:03 +03:00
static void write_frame_header ( FlacEncodeContext * s )
2006-06-24 13:20:15 +03:00
{
FlacFrame * frame ;
int crc ;
frame = & s - > frame ;
put_bits ( & s - > pb , 16 , 0xFFF8 ) ;
put_bits ( & s - > pb , 4 , frame - > bs_code [ 0 ] ) ;
put_bits ( & s - > pb , 4 , s - > sr_code [ 0 ] ) ;
2010-07-30 21:30:09 +03:00
if ( frame - > ch_mode = = FLAC_CHMODE_INDEPENDENT )
2009-03-21 02:45:44 +02:00
put_bits ( & s - > pb , 4 , s - > channels - 1 ) ;
2010-07-30 21:30:09 +03:00
else
2012-06-17 13:45:10 +03:00
put_bits ( & s - > pb , 4 , frame - > ch_mode + FLAC_MAX_CHANNELS - 1 ) ;
2010-07-30 21:30:09 +03:00
2012-10-27 07:26:02 +03:00
put_bits ( & s - > pb , 3 , s - > bps_code ) ;
2006-06-24 13:20:15 +03:00
put_bits ( & s - > pb , 1 , 0 ) ;
write_utf8 ( & s - > pb , s - > frame_count ) ;
2010-07-30 21:30:09 +03:00
if ( frame - > bs_code [ 0 ] = = 6 )
2006-06-26 09:00:07 +03:00
put_bits ( & s - > pb , 8 , frame - > bs_code [ 1 ] ) ;
2010-07-30 21:30:09 +03:00
else if ( frame - > bs_code [ 0 ] = = 7 )
2006-06-26 09:00:07 +03:00
put_bits ( & s - > pb , 16 , frame - > bs_code [ 1 ] ) ;
2010-07-30 21:30:09 +03:00
if ( s - > sr_code [ 0 ] = = 12 )
2006-06-26 09:00:07 +03:00
put_bits ( & s - > pb , 8 , s - > sr_code [ 1 ] ) ;
2010-07-30 21:30:09 +03:00
else if ( s - > sr_code [ 0 ] > 12 )
2006-06-26 09:00:07 +03:00
put_bits ( & s - > pb , 16 , s - > sr_code [ 1 ] ) ;
2010-07-30 21:30:09 +03:00
2006-06-24 13:20:15 +03:00
flush_put_bits ( & s - > pb ) ;
2010-07-30 21:30:09 +03:00
crc = av_crc ( av_crc_get_table ( AV_CRC_8_ATM ) , 0 , s - > pb . buf ,
2021-03-25 13:52:56 +02:00
put_bytes_output ( & s - > pb ) ) ;
2006-06-24 13:20:15 +03:00
put_bits ( & s - > pb , 8 , crc ) ;
}
2010-07-30 21:30:09 +03:00
2022-10-11 19:24:36 +02:00
static inline void set_sr_golomb_flac ( PutBitContext * pb , int i , int k )
{
unsigned v , e ;
v = ( ( unsigned ) ( i ) < < 1 ) ^ ( i > > 31 ) ;
e = ( v > > k ) + 1 ;
while ( e > 31 ) {
put_bits ( pb , 31 , 0 ) ;
e - = 31 ;
}
put_bits ( pb , e , 1 ) ;
if ( k ) {
unsigned mask = UINT32_MAX > > ( 32 - k ) ;
put_bits ( pb , k , v & mask ) ;
}
}
2010-08-01 00:14:03 +03:00
static void write_subframes ( FlacEncodeContext * s )
2006-07-02 13:22:31 +03:00
{
2010-07-31 00:32:19 +03:00
int ch ;
for ( ch = 0 ; ch < s - > channels ; ch + + ) {
FlacSubframe * sub = & s - > frame . subframes [ ch ] ;
2022-10-11 19:24:36 +02:00
int p , porder , psize ;
2010-07-31 00:33:51 +03:00
int32_t * part_end ;
int32_t * res = sub - > residual ;
int32_t * frame_end = & sub - > residual [ s - > frame . blocksize ] ;
2010-07-31 00:06:38 +03:00
2010-07-31 00:32:19 +03:00
/* subframe header */
put_bits ( & s - > pb , 1 , 0 ) ;
put_bits ( & s - > pb , 6 , sub - > type_code ) ;
2012-10-25 22:07:59 +03:00
put_bits ( & s - > pb , 1 , ! ! sub - > wasted ) ;
if ( sub - > wasted )
put_bits ( & s - > pb , sub - > wasted , 1 ) ;
2010-07-31 00:32:19 +03:00
/* subframe */
2010-07-31 00:33:51 +03:00
if ( sub - > type = = FLAC_SUBFRAME_CONSTANT ) {
2022-10-11 19:24:36 +02:00
if ( sub - > obits = = 33 )
put_sbits63 ( & s - > pb , 33 , s - > frame . samples_33bps [ 0 ] ) ;
else if ( sub - > obits = = 32 )
put_bits32 ( & s - > pb , res [ 0 ] ) ;
else
put_sbits ( & s - > pb , sub - > obits , res [ 0 ] ) ;
2010-07-31 00:33:51 +03:00
} else if ( sub - > type = = FLAC_SUBFRAME_VERBATIM ) {
2022-10-11 19:24:36 +02:00
if ( sub - > obits = = 33 ) {
int64_t * res64 = s - > frame . samples_33bps ;
int64_t * frame_end64 = & s - > frame . samples_33bps [ s - > frame . blocksize ] ;
while ( res64 < frame_end64 )
put_sbits63 ( & s - > pb , 33 , ( * res64 + + ) ) ;
} else if ( sub - > obits = = 32 ) {
while ( res < frame_end )
put_bits32 ( & s - > pb , * res + + ) ;
} else {
while ( res < frame_end )
put_sbits ( & s - > pb , sub - > obits , * res + + ) ;
}
2010-07-31 00:33:51 +03:00
} else {
/* warm-up samples */
2022-10-11 19:24:36 +02:00
if ( sub - > obits = = 33 ) {
for ( int i = 0 ; i < sub - > order ; i + + )
put_sbits63 ( & s - > pb , 33 , s - > frame . samples_33bps [ i ] ) ;
res + = sub - > order ;
} else if ( sub - > obits = = 32 ) {
for ( int i = 0 ; i < sub - > order ; i + + )
put_bits32 ( & s - > pb , * res + + ) ;
} else {
for ( int i = 0 ; i < sub - > order ; i + + )
put_sbits ( & s - > pb , sub - > obits , * res + + ) ;
}
2010-07-31 00:33:51 +03:00
/* LPC coefficients */
if ( sub - > type = = FLAC_SUBFRAME_LPC ) {
int cbits = s - > options . lpc_coeff_precision ;
put_bits ( & s - > pb , 4 , cbits - 1 ) ;
put_sbits ( & s - > pb , 5 , sub - > shift ) ;
2022-10-11 19:24:36 +02:00
for ( int i = 0 ; i < sub - > order ; i + + )
2010-07-31 00:33:51 +03:00
put_sbits ( & s - > pb , cbits , sub - > coefs [ i ] ) ;
}
2010-07-31 00:07:21 +03:00
2010-07-31 00:33:51 +03:00
/* rice-encoded block */
2012-10-27 07:46:43 +03:00
put_bits ( & s - > pb , 2 , sub - > rc . coding_mode - 4 ) ;
2010-07-31 00:33:51 +03:00
/* partition order */
porder = sub - > rc . porder ;
psize = s - > frame . blocksize > > porder ;
put_bits ( & s - > pb , 4 , porder ) ;
/* residual */
part_end = & sub - > residual [ psize ] ;
for ( p = 0 ; p < 1 < < porder ; p + + ) {
int k = sub - > rc . params [ p ] ;
2012-10-27 07:46:43 +03:00
put_bits ( & s - > pb , sub - > rc . coding_mode , k ) ;
2010-07-31 00:33:51 +03:00
while ( res < part_end )
2022-10-11 19:24:36 +02:00
set_sr_golomb_flac ( & s - > pb , * res + + , k ) ;
2010-07-31 00:33:51 +03:00
part_end = FFMIN ( frame_end , part_end + psize ) ;
}
2010-07-31 00:07:21 +03:00
}
2010-07-31 00:06:38 +03:00
}
2006-06-24 13:20:15 +03:00
}
2010-07-30 21:30:09 +03:00
2010-08-01 00:14:03 +03:00
static void write_frame_footer ( FlacEncodeContext * s )
2006-06-24 13:20:15 +03:00
{
int crc ;
flush_put_bits ( & s - > pb ) ;
2010-07-30 21:30:09 +03:00
crc = av_bswap16 ( av_crc ( av_crc_get_table ( AV_CRC_16_ANSI ) , 0 , s - > pb . buf ,
2021-03-25 13:52:56 +02:00
put_bytes_output ( & s - > pb ) ) ) ;
2006-06-24 13:20:15 +03:00
put_bits ( & s - > pb , 16 , crc ) ;
flush_put_bits ( & s - > pb ) ;
}
2010-07-30 21:30:09 +03:00
2012-02-04 02:43:39 +03:00
static int write_frame ( FlacEncodeContext * s , AVPacket * avpkt )
2010-07-31 20:23:29 +03:00
{
2012-02-04 02:43:39 +03:00
init_put_bits ( & s - > pb , avpkt - > data , avpkt - > size ) ;
2010-08-01 00:14:03 +03:00
write_frame_header ( s ) ;
write_subframes ( s ) ;
write_frame_footer ( s ) ;
2021-03-25 13:52:56 +02:00
return put_bytes_output ( & s - > pb ) ;
2010-07-31 20:23:29 +03:00
}
2012-10-27 07:26:02 +03:00
static int update_md5_sum ( FlacEncodeContext * s , const void * samples )
2008-09-15 00:39:54 +03:00
{
2012-10-25 22:00:10 +03:00
const uint8_t * buf ;
2012-10-27 07:26:02 +03:00
int buf_size = s - > frame . blocksize * s - > channels *
( ( s - > avctx - > bits_per_raw_sample + 7 ) / 8 ) ;
2012-10-25 22:00:10 +03:00
2012-10-27 07:26:02 +03:00
if ( s - > avctx - > bits_per_raw_sample > 16 | | HAVE_BIGENDIAN ) {
2012-10-25 22:00:10 +03:00
av_fast_malloc ( & s - > md5_buffer , & s - > md5_buffer_size , buf_size ) ;
if ( ! s - > md5_buffer )
return AVERROR ( ENOMEM ) ;
2008-09-15 00:39:54 +03:00
}
2012-10-25 22:00:10 +03:00
2012-10-27 07:26:02 +03:00
if ( s - > avctx - > bits_per_raw_sample < = 16 ) {
buf = ( const uint8_t * ) samples ;
2012-10-25 22:00:10 +03:00
# if HAVE_BIGENDIAN
2014-02-13 19:57:05 +03:00
s - > bdsp . bswap16_buf ( ( uint16_t * ) s - > md5_buffer ,
( const uint16_t * ) samples , buf_size / 2 ) ;
2012-10-27 07:26:02 +03:00
buf = s - > md5_buffer ;
2008-09-15 00:39:54 +03:00
# endif
2022-10-11 19:24:36 +02:00
} else if ( s - > avctx - > bits_per_raw_sample < = 24 ) {
2012-10-27 07:26:02 +03:00
int i ;
const int32_t * samples0 = samples ;
uint8_t * tmp = s - > md5_buffer ;
for ( i = 0 ; i < s - > frame . blocksize * s - > channels ; i + + ) {
int32_t v = samples0 [ i ] > > 8 ;
2015-05-19 19:41:44 +02:00
AV_WL24 ( tmp + 3 * i , v ) ;
2012-10-27 07:26:02 +03:00
}
buf = s - > md5_buffer ;
2022-10-11 19:24:36 +02:00
} else {
/* s->avctx->bits_per_raw_sample <= 32 */
int i ;
const int32_t * samples0 = samples ;
uint8_t * tmp = s - > md5_buffer ;
for ( i = 0 ; i < s - > frame . blocksize * s - > channels ; i + + )
AV_WL32 ( tmp + 4 * i , samples0 [ i ] ) ;
buf = s - > md5_buffer ;
2012-10-27 07:26:02 +03:00
}
2012-10-25 22:00:10 +03:00
av_md5_update ( s - > md5ctx , buf , buf_size ) ;
return 0 ;
2008-09-15 00:39:54 +03:00
}
2010-07-30 21:30:09 +03:00
2012-02-04 02:43:39 +03:00
static int flac_encode_frame ( AVCodecContext * avctx , AVPacket * avpkt ,
const AVFrame * frame , int * got_packet_ptr )
2006-06-24 13:20:15 +03:00
{
FlacEncodeContext * s ;
2012-02-04 02:43:39 +03:00
int frame_bytes , out_bytes , ret ;
2006-06-24 13:20:15 +03:00
s = avctx - > priv_data ;
2008-09-14 23:00:36 +03:00
/* when the last block is reached, update the header in extradata */
2012-02-04 02:43:39 +03:00
if ( ! frame ) {
2008-09-15 01:25:50 +03:00
s - > max_framesize = s - > max_encoded_framesize ;
2008-09-15 00:39:54 +03:00
av_md5_final ( s - > md5ctx , s - > md5sum ) ;
2008-09-14 23:00:36 +03:00
write_streaminfo ( s , avctx - > extradata ) ;
2014-04-29 16:11:30 +03:00
2015-09-11 17:47:29 +02:00
if ( ! s - > flushed ) {
2014-04-29 16:11:30 +03:00
uint8_t * side_data = av_packet_new_side_data ( avpkt , AV_PKT_DATA_NEW_EXTRADATA ,
avctx - > extradata_size ) ;
if ( ! side_data )
return AVERROR ( ENOMEM ) ;
memcpy ( side_data , avctx - > extradata , avctx - > extradata_size ) ;
avpkt - > pts = s - > next_pts ;
* got_packet_ptr = 1 ;
s - > flushed = 1 ;
}
2008-09-14 23:00:36 +03:00
return 0 ;
}
2010-07-31 23:52:33 +03:00
/* change max_framesize for small final frame */
2012-02-04 02:43:39 +03:00
if ( frame - > nb_samples < s - > frame . blocksize ) {
2022-08-28 15:21:27 +02:00
s - > max_framesize = flac_get_max_frame_size ( frame - > nb_samples ,
s - > channels ,
avctx - > bits_per_raw_sample ) ;
2010-07-31 23:52:33 +03:00
}
2012-02-04 02:43:39 +03:00
init_frame ( s , frame - > nb_samples ) ;
2006-06-24 13:20:15 +03:00
2012-10-27 07:26:02 +03:00
copy_samples ( s , frame - > data [ 0 ] ) ;
2006-06-24 13:20:15 +03:00
2006-06-26 09:00:07 +03:00
channel_decorrelation ( s ) ;
2012-10-25 22:07:59 +03:00
remove_wasted_bits ( s ) ;
2010-07-31 23:32:12 +03:00
frame_bytes = encode_frame ( s ) ;
2006-06-24 13:20:15 +03:00
2012-08-21 02:02:13 +03:00
/* Fall back on verbatim mode if the compressed frame is larger than it
2010-07-31 20:23:29 +03:00
would be if encoded uncompressed . */
2012-10-27 06:22:38 +03:00
if ( frame_bytes < 0 | | frame_bytes > s - > max_framesize ) {
2010-07-31 19:46:32 +03:00
s - > frame . verbatim_only = 1 ;
2010-07-31 23:32:12 +03:00
frame_bytes = encode_frame ( s ) ;
2012-10-27 06:22:38 +03:00
if ( frame_bytes < 0 ) {
av_log ( avctx , AV_LOG_ERROR , " Bad frame count \n " ) ;
return frame_bytes ;
}
2006-06-24 13:20:15 +03:00
}
2021-04-25 01:43:26 +02:00
if ( ( ret = ff_get_encode_buffer ( avctx , avpkt , frame_bytes , 0 ) ) < 0 )
2012-02-04 02:43:39 +03:00
return ret ;
out_bytes = write_frame ( s , avpkt ) ;
2010-08-01 00:08:53 +03:00
2006-06-24 13:20:15 +03:00
s - > frame_count + + ;
2012-02-04 02:43:39 +03:00
s - > sample_count + = frame - > nb_samples ;
2012-10-27 07:26:02 +03:00
if ( ( ret = update_md5_sum ( s , frame - > data [ 0 ] ) ) < 0 ) {
2012-10-25 22:00:10 +03:00
av_log ( avctx , AV_LOG_ERROR , " Error updating MD5 checksum \n " ) ;
return ret ;
}
2008-09-15 01:25:50 +03:00
if ( out_bytes > s - > max_encoded_framesize )
s - > max_encoded_framesize = out_bytes ;
2009-03-21 02:50:19 +02:00
if ( out_bytes < s - > min_framesize )
s - > min_framesize = out_bytes ;
2008-09-14 23:00:36 +03:00
2023-01-25 17:39:01 +02:00
s - > next_pts = frame - > pts + ff_samples_to_time_base ( avctx , frame - > nb_samples ) ;
2014-04-29 16:11:30 +03:00
2021-04-25 01:43:26 +02:00
av_shrink_packet ( avpkt , out_bytes ) ;
2012-02-04 02:43:39 +03:00
* got_packet_ptr = 1 ;
return 0 ;
2006-06-24 13:20:15 +03:00
}
2010-07-30 21:30:09 +03:00
2008-03-21 05:11:20 +02:00
static av_cold int flac_encode_close ( AVCodecContext * avctx )
2006-06-24 13:20:15 +03:00
{
2020-11-29 23:32:34 +02:00
FlacEncodeContext * s = avctx - > priv_data ;
av_freep ( & s - > md5ctx ) ;
av_freep ( & s - > md5_buffer ) ;
ff_lpc_end ( & s - > lpc_ctx ) ;
2006-06-24 13:20:15 +03:00
return 0 ;
}
2011-04-02 13:28:01 +03:00
# define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static const AVOption options [ ] = {
2012-08-31 13:22:31 +03:00
{ " lpc_coeff_precision " , " LPC coefficient precision " , offsetof ( FlacEncodeContext , options . lpc_coeff_precision ) , AV_OPT_TYPE_INT , { . i64 = 15 } , 0 , MAX_LPC_PRECISION , FLAGS } ,
{ " lpc_type " , " LPC algorithm " , offsetof ( FlacEncodeContext , options . lpc_type ) , AV_OPT_TYPE_INT , { . i64 = FF_LPC_TYPE_DEFAULT } , FF_LPC_TYPE_DEFAULT , FF_LPC_TYPE_NB - 1 , FLAGS , " lpc_type " } ,
2012-08-31 12:45:52 +03:00
{ " none " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = FF_LPC_TYPE_NONE } , INT_MIN , INT_MAX , FLAGS , " lpc_type " } ,
{ " fixed " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = FF_LPC_TYPE_FIXED } , INT_MIN , INT_MAX , FLAGS , " lpc_type " } ,
{ " levinson " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = FF_LPC_TYPE_LEVINSON } , INT_MIN , INT_MAX , FLAGS , " lpc_type " } ,
{ " cholesky " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = FF_LPC_TYPE_CHOLESKY } , INT_MIN , INT_MAX , FLAGS , " lpc_type " } ,
2012-12-07 17:45:25 +03:00
{ " lpc_passes " , " Number of passes to use for Cholesky factorization during LPC analysis " , offsetof ( FlacEncodeContext , options . lpc_passes ) , AV_OPT_TYPE_INT , { . i64 = 2 } , 1 , INT_MAX , FLAGS } ,
2012-08-31 13:22:31 +03:00
{ " min_partition_order " , NULL , offsetof ( FlacEncodeContext , options . min_partition_order ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , MAX_PARTITION_ORDER , FLAGS } ,
{ " max_partition_order " , NULL , offsetof ( FlacEncodeContext , options . max_partition_order ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , MAX_PARTITION_ORDER , FLAGS } ,
{ " prediction_order_method " , " Search method for selecting prediction order " , offsetof ( FlacEncodeContext , options . prediction_order_method ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , ORDER_METHOD_LOG , FLAGS , " predm " } ,
2012-08-31 12:45:52 +03:00
{ " estimation " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = ORDER_METHOD_EST } , INT_MIN , INT_MAX , FLAGS , " predm " } ,
{ " 2level " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = ORDER_METHOD_2LEVEL } , INT_MIN , INT_MAX , FLAGS , " predm " } ,
{ " 4level " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = ORDER_METHOD_4LEVEL } , INT_MIN , INT_MAX , FLAGS , " predm " } ,
{ " 8level " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = ORDER_METHOD_8LEVEL } , INT_MIN , INT_MAX , FLAGS , " predm " } ,
{ " search " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = ORDER_METHOD_SEARCH } , INT_MIN , INT_MAX , FLAGS , " predm " } ,
{ " log " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = ORDER_METHOD_LOG } , INT_MIN , INT_MAX , FLAGS , " predm " } ,
2012-08-31 13:22:31 +03:00
{ " ch_mode " , " Stereo decorrelation mode " , offsetof ( FlacEncodeContext , options . ch_mode ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , FLAC_CHMODE_MID_SIDE , FLAGS , " ch_mode " } ,
2012-08-31 12:45:52 +03:00
{ " auto " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = - 1 } , INT_MIN , INT_MAX , FLAGS , " ch_mode " } ,
{ " indep " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = FLAC_CHMODE_INDEPENDENT } , INT_MIN , INT_MAX , FLAGS , " ch_mode " } ,
{ " left_side " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = FLAC_CHMODE_LEFT_SIDE } , INT_MIN , INT_MAX , FLAGS , " ch_mode " } ,
{ " right_side " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = FLAC_CHMODE_RIGHT_SIDE } , INT_MIN , INT_MAX , FLAGS , " ch_mode " } ,
{ " mid_side " , NULL , 0 , AV_OPT_TYPE_CONST , { . i64 = FLAC_CHMODE_MID_SIDE } , INT_MIN , INT_MAX , FLAGS , " ch_mode " } ,
2015-11-21 23:04:39 +02:00
{ " exact_rice_parameters " , " Calculate rice parameters exactly " , offsetof ( FlacEncodeContext , options . exact_rice_parameters ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , FLAGS } ,
{ " multi_dim_quant " , " Multi-dimensional quantization " , offsetof ( FlacEncodeContext , options . multi_dim_quant ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , FLAGS } ,
2016-01-31 20:25:29 +02:00
{ " min_prediction_order " , NULL , offsetof ( FlacEncodeContext , options . min_prediction_order ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , MAX_LPC_ORDER , FLAGS } ,
{ " max_prediction_order " , NULL , offsetof ( FlacEncodeContext , options . max_prediction_order ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , MAX_LPC_ORDER , FLAGS } ,
2015-09-13 23:45:24 +02:00
2011-04-02 13:28:01 +03:00
{ NULL } ,
} ;
static const AVClass flac_encoder_class = {
2015-12-20 18:47:21 +02:00
. class_name = " FLAC encoder " ,
2024-01-19 14:33:28 +02:00
. item_name = av_default_item_name ,
2015-12-20 18:47:21 +02:00
. option = options ,
. version = LIBAVUTIL_VERSION_INT ,
2011-04-02 13:28:01 +03:00
} ;
2010-07-30 21:30:09 +03:00
2022-03-16 22:09:54 +02:00
const FFCodec ff_flac_encoder = {
. p . name = " flac " ,
2022-08-29 13:38:02 +02:00
CODEC_LONG_NAME ( " FLAC (Free Lossless Audio Codec) " ) ,
2022-03-16 22:09:54 +02:00
. p . type = AVMEDIA_TYPE_AUDIO ,
. p . id = AV_CODEC_ID_FLAC ,
. p . capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
2022-11-27 14:37:10 +02:00
AV_CODEC_CAP_SMALL_LAST_FRAME |
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE ,
2011-07-17 13:54:31 +03:00
. priv_data_size = sizeof ( FlacEncodeContext ) ,
. init = flac_encode_init ,
2022-03-30 23:28:24 +02:00
FF_CODEC_ENCODE_CB ( flac_encode_frame ) ,
2011-07-17 13:54:31 +03:00
. close = flac_encode_close ,
2022-03-16 22:09:54 +02:00
. p . sample_fmts = ( const enum AVSampleFormat [ ] ) { AV_SAMPLE_FMT_S16 ,
2012-10-27 07:26:02 +03:00
AV_SAMPLE_FMT_S32 ,
2012-04-06 19:19:39 +03:00
AV_SAMPLE_FMT_NONE } ,
2022-03-16 22:09:54 +02:00
. p . priv_class = & flac_encoder_class ,
2023-01-25 17:39:01 +02:00
. caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_EOF_FLUSH ,
2006-06-24 13:20:15 +03:00
} ;