@ -32,6 +32,7 @@
# include "lpc.h"
# include "flac.h"
# include "flacdata.h"
# include "flacdsp.h"
# define FLAC_SUBFRAME_CONSTANT 0
# define FLAC_SUBFRAME_VERBATIM 1
@ -43,7 +44,11 @@
# define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER)
# define MAX_LPC_PRECISION 15
# define MAX_LPC_SHIFT 15
# define MAX_RICE_PARAM 14
enum CodingMode {
CODING_MODE_RICE = 4 ,
CODING_MODE_RICE2 = 5 ,
} ;
typedef struct CompressionOptions {
int compression_level ;
@ -60,6 +65,7 @@ typedef struct CompressionOptions {
} CompressionOptions ;
typedef struct RiceContext {
enum CodingMode coding_mode ;
int porder ;
int params [ MAX_PARTITIONS ] ;
} RiceContext ;
@ -92,6 +98,7 @@ typedef struct FlacEncodeContext {
int channels ;
int samplerate ;
int sr_code [ 2 ] ;
int bps_code ;
int max_blocksize ;
int min_framesize ;
int max_framesize ;
@ -107,6 +114,7 @@ typedef struct FlacEncodeContext {
uint8_t * md5_buffer ;
unsigned int md5_buffer_size ;
DSPContext dsp ;
FLACDSPContext flac_dsp ;
} FlacEncodeContext ;
@ -127,7 +135,7 @@ static void write_streaminfo(FlacEncodeContext *s, uint8_t *header)
put_bits ( & pb , 24 , s - > max_framesize ) ;
put_bits ( & pb , 20 , s - > samplerate ) ;
put_bits ( & pb , 3 , s - > channels - 1 ) ;
put_bits ( & pb , 5 , 15 ) ; /* bits per sample - 1 */
put_bits ( & pb , 5 , s - > avctx - > bits_per_raw_sample - 1 ) ;
/* 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 ) ;
@ -227,8 +235,18 @@ static av_cold int flac_encode_init(AVCodecContext *avctx)
s - > avctx = avctx ;
if ( avctx - > sample_fmt ! = AV_SAMPLE_FMT_S16 )
return - 1 ;
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 :
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 ;
break ;
}
if ( channels < 1 | | channels > FLAC_MAX_CHANNELS )
return - 1 ;
@ -358,7 +376,8 @@ static av_cold int flac_encode_init(AVCodecContext *avctx)
/* set maximum encoded frame size in verbatim mode */
s - > max_framesize = ff_flac_get_max_frame_size ( s - > avctx - > frame_size ,
s - > channels , 16 ) ;
s - > channels ,
s - > avctx - > bits_per_raw_sample ) ;
/* initialize MD5 context */
s - > md5ctx = av_md5_alloc ( ) ;
@ -408,6 +427,8 @@ static av_cold int flac_encode_init(AVCodecContext *avctx)
s - > options . max_prediction_order , FF_LPC_TYPE_LEVINSON ) ;
ff_dsputil_init ( & s - > dsp , avctx ) ;
ff_flacdsp_init ( & s - > flac_dsp , avctx - > sample_fmt ,
avctx - > bits_per_raw_sample ) ;
dprint_compression_options ( s ) ;
@ -442,8 +463,15 @@ static void init_frame(FlacEncodeContext *s, int nb_samples)
}
for ( ch = 0 ; ch < s - > channels ; ch + + ) {
frame - > subframes [ ch ] . wasted = 0 ;
frame - > subframes [ ch ] . obits = 16 ;
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 ;
}
frame - > verbatim_only = 0 ;
@ -453,15 +481,25 @@ static void init_frame(FlacEncodeContext *s, int nb_samples)
/**
* Copy channel - interleaved input samples into separate subframes .
*/
static void copy_samples ( FlacEncodeContext * s , const int16_t * samples )
static void copy_samples ( FlacEncodeContext * s , const void * samples )
{
int i , j , ch ;
FlacFrame * frame ;
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 ] = samples [ j ] ;
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 ) ;
}
@ -515,7 +553,7 @@ static uint64_t subframe_count_exact(FlacEncodeContext *s, FlacSubframe *sub,
part_end = psize ;
for ( p = 0 ; p < 1 < < porder ; p + + ) {
int k = sub - > rc . params [ p ] ;
count + = 4 ;
count + = sub - > rc . coding_mode ;
count + = rice_count_exact ( & sub - > residual [ i ] , part_end - i , k ) ;
i = part_end ;
part_end = FFMIN ( s - > frame . blocksize , part_end + psize ) ;
@ -531,7 +569,7 @@ static uint64_t subframe_count_exact(FlacEncodeContext *s, FlacSubframe *sub,
/**
* Solve for d / dk ( rice_encode_count ) = n - ( ( sum - ( n > > 1 ) ) > > ( k + 1 ) ) = 0.
*/
static int find_optimal_param ( uint64_t sum , int n )
static int find_optimal_param ( uint64_t sum , int n , int max_param )
{
int k ;
uint64_t sum2 ;
@ -540,7 +578,7 @@ static int find_optimal_param(uint64_t sum, int n)
return 0 ;
sum2 = sum - ( n > > 1 ) ;
k = av_log2 ( av_clipl_int32 ( sum2 / n ) ) ;
return FFMIN ( k , MAX_RICE_PARAM ) ;
return FFMIN ( k , max_param ) ;
}
@ -548,15 +586,17 @@ static uint64_t calc_optimal_rice_params(RiceContext *rc, int porder,
uint64_t * sums , int n , int pred_order )
{
int i ;
int k , cnt , part ;
int k , cnt , part , max_param ;
uint64_t all_bits ;
max_param = ( 1 < < rc - > coding_mode ) - 2 ;
part = ( 1 < < porder ) ;
all_bits = 4 * part ;
cnt = ( n > > porder ) - pred_order ;
for ( i = 0 ; i < part ; i + + ) {
k = find_optimal_param ( sums [ i ] , cnt ) ;
k = find_optimal_param ( sums [ i ] , cnt , max_param ) ;
rc - > params [ i ] = k ;
all_bits + = rice_encode_count ( sums [ i ] , cnt , k ) ;
cnt = n > > porder ;
@ -609,6 +649,8 @@ static uint64_t calc_rice_params(RiceContext *rc, int pmin, int pmax,
av_assert1 ( pmax > = 0 & & pmax < = MAX_PARTITION_ORDER ) ;
av_assert1 ( pmin < = pmax ) ;
tmp_rc . coding_mode = rc - > coding_mode ;
udata = av_malloc ( n * sizeof ( uint32_t ) ) ;
for ( i = 0 ; i < n ; i + + )
udata [ i ] = ( 2 * data [ i ] ) ^ ( data [ i ] > > 31 ) ;
@ -647,7 +689,7 @@ static uint64_t find_subframe_rice_params(FlacEncodeContext *s,
int pmax = get_max_p_order ( s - > options . max_partition_order ,
s - > frame . blocksize , pred_order ) ;
uint64_t bits = 8 + pred_order * sub - > obits + 2 + 4 ;
uint64_t bits = 8 + pred_order * sub - > obits + 2 + sub - > rc . coding_mode ;
if ( sub - > type = = FLAC_SUBFRAME_LPC )
bits + = 4 + 5 + pred_order * s - > options . lpc_coeff_precision ;
bits + = calc_rice_params ( & sub - > rc , pmin , pmax , sub - > residual ,
@ -707,110 +749,6 @@ static void encode_residual_fixed(int32_t *res, const int32_t *smp, int n,
}
# define LPC1(x) {\
int c = coefs [ ( x ) - 1 ] ; \
p0 + = c * s ; \
s = smp [ i - ( x ) + 1 ] ; \
p1 + = c * s ; \
}
static av_always_inline void encode_residual_lpc_unrolled ( int32_t * res ,
const int32_t * smp , int n , int order ,
const int32_t * coefs , int shift , int big )
{
int i ;
for ( i = order ; i < n ; i + = 2 ) {
int s = smp [ i - order ] ;
int p0 = 0 , p1 = 0 ;
if ( big ) {
switch ( order ) {
case 32 : LPC1 ( 32 )
case 31 : LPC1 ( 31 )
case 30 : LPC1 ( 30 )
case 29 : LPC1 ( 29 )
case 28 : LPC1 ( 28 )
case 27 : LPC1 ( 27 )
case 26 : LPC1 ( 26 )
case 25 : LPC1 ( 25 )
case 24 : LPC1 ( 24 )
case 23 : LPC1 ( 23 )
case 22 : LPC1 ( 22 )
case 21 : LPC1 ( 21 )
case 20 : LPC1 ( 20 )
case 19 : LPC1 ( 19 )
case 18 : LPC1 ( 18 )
case 17 : LPC1 ( 17 )
case 16 : LPC1 ( 16 )
case 15 : LPC1 ( 15 )
case 14 : LPC1 ( 14 )
case 13 : LPC1 ( 13 )
case 12 : LPC1 ( 12 )
case 11 : LPC1 ( 11 )
case 10 : LPC1 ( 10 )
case 9 : LPC1 ( 9 )
LPC1 ( 8 )
LPC1 ( 7 )
LPC1 ( 6 )
LPC1 ( 5 )
LPC1 ( 4 )
LPC1 ( 3 )
LPC1 ( 2 )
LPC1 ( 1 )
}
} else {
switch ( order ) {
case 8 : LPC1 ( 8 )
case 7 : LPC1 ( 7 )
case 6 : LPC1 ( 6 )
case 5 : LPC1 ( 5 )
case 4 : LPC1 ( 4 )
case 3 : LPC1 ( 3 )
case 2 : LPC1 ( 2 )
case 1 : LPC1 ( 1 )
}
}
res [ i ] = smp [ i ] - ( p0 > > shift ) ;
res [ i + 1 ] = smp [ i + 1 ] - ( p1 > > shift ) ;
}
}
static void encode_residual_lpc ( int32_t * res , const int32_t * smp , int n ,
int order , const int32_t * coefs , int shift )
{
int i ;
for ( i = 0 ; i < order ; i + + )
res [ i ] = smp [ i ] ;
# if CONFIG_SMALL
for ( i = order ; i < n ; i + = 2 ) {
int j ;
int s = smp [ i ] ;
int p0 = 0 , p1 = 0 ;
for ( j = 0 ; j < order ; j + + ) {
int c = coefs [ j ] ;
p1 + = c * s ;
s = smp [ i - j - 1 ] ;
p0 + = c * s ;
}
res [ i ] = smp [ i ] - ( p0 > > shift ) ;
res [ i + 1 ] = smp [ i + 1 ] - ( p1 > > shift ) ;
}
# else
switch ( order ) {
case 1 : encode_residual_lpc_unrolled ( res , smp , n , 1 , coefs , shift , 0 ) ; break ;
case 2 : encode_residual_lpc_unrolled ( res , smp , n , 2 , coefs , shift , 0 ) ; break ;
case 3 : encode_residual_lpc_unrolled ( res , smp , n , 3 , coefs , shift , 0 ) ; break ;
case 4 : encode_residual_lpc_unrolled ( res , smp , n , 4 , coefs , shift , 0 ) ; break ;
case 5 : encode_residual_lpc_unrolled ( res , smp , n , 5 , coefs , shift , 0 ) ; break ;
case 6 : encode_residual_lpc_unrolled ( res , smp , n , 6 , coefs , shift , 0 ) ; break ;
case 7 : encode_residual_lpc_unrolled ( res , smp , n , 7 , coefs , shift , 0 ) ; break ;
case 8 : encode_residual_lpc_unrolled ( res , smp , n , 8 , coefs , shift , 0 ) ; break ;
default : encode_residual_lpc_unrolled ( res , smp , n , order , coefs , shift , 1 ) ; break ;
}
# endif
}
static int encode_residual_ch ( FlacEncodeContext * s , int ch )
{
int i , n ;
@ -892,7 +830,8 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
order = min_order + ( ( ( max_order - min_order + 1 ) * ( i + 1 ) ) / levels ) - 1 ;
if ( order < 0 )
order = 0 ;
encode_residual_lpc ( res , smp , n , order + 1 , coefs [ order ] , shift [ order ] ) ;
s - > flac_dsp . lpc_encode ( res , smp , n , order + 1 , coefs [ order ] ,
shift [ order ] ) ;
bits [ i ] = find_subframe_rice_params ( s , sub , order + 1 ) ;
if ( bits [ i ] < bits [ opt_index ] ) {
opt_index = i ;
@ -906,7 +845,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
opt_order = 0 ;
bits [ 0 ] = UINT32_MAX ;
for ( i = min_order - 1 ; i < max_order ; i + + ) {
encode_residual_lpc ( res , smp , n , i + 1 , coefs [ i ] , shift [ i ] ) ;
s - > flac_dsp . lpc_encode ( res , smp , n , i + 1 , coefs [ i ] , shift [ i ] ) ;
bits [ i ] = find_subframe_rice_params ( s , sub , i + 1 ) ;
if ( bits [ i ] < bits [ opt_order ] )
opt_order = i ;
@ -924,7 +863,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
for ( i = last - step ; i < = last + step ; i + = step ) {
if ( i < min_order - 1 | | i > = max_order | | bits [ i ] < UINT32_MAX )
continue ;
encode_residual_lpc ( res , smp , n , i + 1 , coefs [ i ] , shift [ i ] ) ;
s - > flac_dsp . lpc_encode ( res , smp , n , i + 1 , coefs [ i ] , shift [ i ] ) ;
bits [ i ] = find_subframe_rice_params ( s , sub , i + 1 ) ;
if ( bits [ i ] < bits [ opt_order ] )
opt_order = i ;
@ -939,7 +878,7 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
for ( i = 0 ; i < sub - > order ; i + + )
sub - > coefs [ i ] = coefs [ sub - > order - 1 ] [ i ] ;
encode_residual_lpc ( res , smp , n , sub - > order , sub - > coefs , sub - > shift ) ;
s - > flac_dsp . lpc_encode ( res , smp , n , sub - > order , sub - > coefs , sub - > shift ) ;
find_subframe_rice_params ( s , sub , sub - > order ) ;
@ -1025,12 +964,18 @@ static void remove_wasted_bits(FlacEncodeContext *s)
sub - > wasted = v ;
sub - > obits - = v ;
/* 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 ;
}
}
}
static int estimate_stereo_mode ( int32_t * left_ch , int32_t * right_ch , int n )
static int estimate_stereo_mode ( int32_t * left_ch , int32_t * right_ch , int n ,
int max_rice_param )
{
int i , best ;
int32_t lt , rt ;
@ -1050,7 +995,7 @@ static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n)
}
/* estimate bit counts */
for ( i = 0 ; i < 4 ; i + + ) {
k = find_optimal_param ( 2 * sum [ i ] , n ) ;
k = find_optimal_param ( 2 * sum [ i ] , n , max_rice_param ) ;
sum [ i ] = rice_encode_count ( 2 * sum [ i ] , n , k ) ;
}
@ -1089,9 +1034,10 @@ static void channel_decorrelation(FlacEncodeContext *s)
return ;
}
if ( s - > options . ch_mode < 0 )
frame - > ch_mode = estimate_stereo_mode ( left , right , n ) ;
else
if ( s - > options . ch_mode < 0 ) {
int max_rice_param = ( 1 < < frame - > subframes [ 0 ] . rc . coding_mode ) - 2 ;
frame - > ch_mode = estimate_stereo_mode ( left , right , n , max_rice_param ) ;
} else
frame - > ch_mode = s - > options . ch_mode ;
/* perform decorrelation and adjust bits-per-sample */
@ -1140,7 +1086,7 @@ static void write_frame_header(FlacEncodeContext *s)
else
put_bits ( & s - > pb , 4 , frame - > ch_mode + FLAC_MAX_CHANNELS - 1 ) ;
put_bits ( & s - > pb , 3 , 4 ) ; /* bits-per-sample code */
put_bits ( & s - > pb , 3 , s - > bps_code ) ;
put_bits ( & s - > pb , 1 , 0 ) ;
write_utf8 ( & s - > pb , s - > frame_count ) ;
@ -1200,7 +1146,7 @@ static void write_subframes(FlacEncodeContext *s)
}
/* rice-encoded block */
put_bits ( & s - > pb , 2 , 0 ) ;
put_bits ( & s - > pb , 2 , sub - > rc . coding_mode - 4 ) ;
/* partition order */
porder = sub - > rc . porder ;
@ -1211,7 +1157,7 @@ static void write_subframes(FlacEncodeContext *s)
part_end = & sub - > residual [ psize ] ;
for ( p = 0 ; p < 1 < < porder ; p + + ) {
int k = sub - > rc . params [ p ] ;
put_bits ( & s - > pb , 4 , k ) ;
put_bits ( & s - > pb , sub - > rc . coding_mode , k ) ;
while ( res < part_end )
set_sr_golomb_flac ( & s - > pb , * res + + , k , INT32_MAX , 0 ) ;
part_end = FFMIN ( frame_end , part_end + psize ) ;
@ -1242,23 +1188,38 @@ static int write_frame(FlacEncodeContext *s, AVPacket *avpkt)
}
static int update_md5_sum ( FlacEncodeContext * s , const int16_t * samples )
static int update_md5_sum ( FlacEncodeContext * s , const void * samples )
{
const uint8_t * buf ;
int buf_size = s - > frame . blocksize * s - > channels * 2 ;
int buf_size = s - > frame . blocksize * s - > channels *
( ( s - > avctx - > bits_per_raw_sample + 7 ) / 8 ) ;
if ( HAVE_BIGENDIAN ) {
if ( s - > avctx - > bits_per_raw_sample > 16 | | HAVE_BIGENDIAN ) {
av_fast_malloc ( & s - > md5_buffer , & s - > md5_buffer_size , buf_size ) ;
if ( ! s - > md5_buffer )
return AVERROR ( ENOMEM ) ;
}
buf = ( const uint8_t * ) samples ;
if ( s - > avctx - > bits_per_raw_sample < = 16 ) {
buf = ( const uint8_t * ) samples ;
# if HAVE_BIGENDIAN
s - > dsp . bswap16_buf ( ( uint16_t * ) s - > md5_buffer ,
( const uint16_t * ) samples , buf_size / 2 ) ;
buf = s - > md5_buffer ;
s - > dsp . bswap16_buf ( ( uint16_t * ) s - > md5_buffer ,
( const uint16_t * ) samples , buf_size / 2 ) ;
buf = s - > md5_buffer ;
# endif
} else {
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 ;
* tmp + + = ( v ) & 0xFF ;
* tmp + + = ( v > > 8 ) & 0xFF ;
* tmp + + = ( v > > 16 ) & 0xFF ;
}
buf = s - > md5_buffer ;
}
av_md5_update ( s - > md5ctx , buf , buf_size ) ;
return 0 ;
@ -1269,7 +1230,6 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
const AVFrame * frame , int * got_packet_ptr )
{
FlacEncodeContext * s ;
const int16_t * samples ;
int frame_bytes , out_bytes , ret ;
s = avctx - > priv_data ;
@ -1281,17 +1241,17 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
write_streaminfo ( s , avctx - > extradata ) ;
return 0 ;
}
samples = ( const int16_t * ) frame - > data [ 0 ] ;
/* change max_framesize for small final frame */
if ( frame - > nb_samples < s - > frame . blocksize ) {
s - > max_framesize = ff_flac_get_max_frame_size ( frame - > nb_samples ,
s - > channels , 16 ) ;
s - > channels ,
avctx - > bits_per_raw_sample ) ;
}
init_frame ( s , frame - > nb_samples ) ;
copy_samples ( s , samples ) ;
copy_samples ( s , frame - > data [ 0 ] ) ;
channel_decorrelation ( s ) ;
@ -1317,7 +1277,7 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
s - > frame_count + + ;
s - > sample_count + = frame - > nb_samples ;
if ( ( ret = update_md5_sum ( s , samples ) ) < 0 ) {
if ( ( ret = update_md5_sum ( s , frame - > data [ 0 ] ) ) < 0 ) {
av_log ( avctx , AV_LOG_ERROR , " Error updating MD5 checksum \n " ) ;
return ret ;
}
@ -1394,6 +1354,7 @@ AVCodec ff_flac_encoder = {
. close = flac_encode_close ,
. capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | CODEC_CAP_LOSSLESS ,
. sample_fmts = ( const enum AVSampleFormat [ ] ) { AV_SAMPLE_FMT_S16 ,
AV_SAMPLE_FMT_S32 ,
AV_SAMPLE_FMT_NONE } ,
. long_name = NULL_IF_CONFIG_SMALL ( " FLAC (Free Lossless Audio Codec) " ) ,
. priv_class = & flac_encoder_class ,