@ -39,11 +39,17 @@
# define FLAC_STREAMINFO_SIZE 34
typedef struct RiceContext {
int porder ;
int params [ 256 ] ;
} RiceContext ;
typedef struct FlacSubframe {
int type ;
int type_code ;
int obits ;
int order ;
RiceContext rc ;
int32_t samples [ FLAC_MAX_BLOCKSIZE ] ;
int32_t residual [ FLAC_MAX_BLOCKSIZE ] ;
} FlacSubframe ;
@ -66,6 +72,7 @@ typedef struct FlacEncodeContext {
int max_framesize ;
uint32_t frame_count ;
FlacFrame frame ;
AVCodecContext * avctx ;
} FlacEncodeContext ;
static const int flac_samplerates [ 16 ] = {
@ -105,7 +112,7 @@ static void write_streaminfo(FlacEncodeContext *s, uint8_t *header)
/* MD5 signature = 0 */
}
# define BLOCK_TIME_MS 105
# define BLOCK_TIME_MS 27
/**
* Sets blocksize based on samplerate
@ -136,6 +143,8 @@ static int flac_encode_init(AVCodecContext *avctx)
int i ;
uint8_t * streaminfo ;
s - > avctx = avctx ;
if ( avctx - > sample_fmt ! = SAMPLE_FMT_S16 ) {
return - 1 ;
}
@ -244,29 +253,283 @@ static void copy_samples(FlacEncodeContext *s, int16_t *samples)
}
}
# define rice_encode_count(sum, n, k) (((n)*((k)+1))+((sum-(n>>1))>>(k)))
static int find_optimal_param ( uint32_t sum , int n )
{
int k , k_opt ;
uint32_t nbits , nbits_opt ;
k_opt = 0 ;
nbits_opt = rice_encode_count ( sum , n , 0 ) ;
for ( k = 1 ; k < = 14 ; k + + ) {
nbits = rice_encode_count ( sum , n , k ) ;
if ( nbits < nbits_opt ) {
nbits_opt = nbits ;
k_opt = k ;
}
}
return k_opt ;
}
static uint32_t calc_optimal_rice_params ( RiceContext * rc , int porder ,
uint32_t * sums , int n , int pred_order )
{
int i ;
int k , cnt , part ;
uint32_t all_bits ;
part = ( 1 < < porder ) ;
all_bits = 0 ;
cnt = ( n > > porder ) - pred_order ;
for ( i = 0 ; i < part ; i + + ) {
if ( i = = 1 ) cnt = ( n > > porder ) ;
k = find_optimal_param ( sums [ i ] , cnt ) ;
rc - > params [ i ] = k ;
all_bits + = rice_encode_count ( sums [ i ] , cnt , k ) ;
}
all_bits + = ( 4 * part ) ;
rc - > porder = porder ;
return all_bits ;
}
static void calc_sums ( int pmax , uint32_t * data , int n , int pred_order ,
uint32_t sums [ ] [ 256 ] )
{
int i , j ;
int parts , cnt ;
uint32_t * res ;
/* sums for highest level */
parts = ( 1 < < pmax ) ;
res = & data [ pred_order ] ;
cnt = ( n > > pmax ) - pred_order ;
for ( i = 0 ; i < parts ; i + + ) {
if ( i = = 1 ) cnt = ( n > > pmax ) ;
if ( i > 0 ) res = & data [ i * cnt ] ;
sums [ pmax ] [ i ] = 0 ;
for ( j = 0 ; j < cnt ; j + + ) {
sums [ pmax ] [ i ] + = res [ j ] ;
}
}
/* sums for lower levels */
for ( i = pmax - 1 ; i > = 0 ; i - - ) {
parts = ( 1 < < i ) ;
for ( j = 0 ; j < parts ; j + + ) {
sums [ i ] [ j ] = sums [ i + 1 ] [ 2 * j ] + sums [ i + 1 ] [ 2 * j + 1 ] ;
}
}
}
static uint32_t calc_rice_params ( RiceContext * rc , int pmax , int32_t * data ,
int n , int pred_order )
{
int i ;
uint32_t bits , opt_bits ;
int opt_porder ;
RiceContext opt_rc ;
uint32_t * udata ;
uint32_t sums [ 9 ] [ 256 ] ;
assert ( pmax > = 0 & & pmax < = 8 ) ;
udata = av_malloc ( n * sizeof ( uint32_t ) ) ;
for ( i = 0 ; i < n ; i + + ) {
udata [ i ] = ( 2 * data [ i ] ) ^ ( data [ i ] > > 31 ) ;
}
calc_sums ( pmax , udata , n , pred_order , sums ) ;
opt_porder = 0 ;
opt_bits = UINT32_MAX ;
for ( i = 0 ; i < = pmax ; i + + ) {
bits = calc_optimal_rice_params ( rc , i , sums [ i ] , n , pred_order ) ;
if ( bits < opt_bits ) {
opt_bits = bits ;
opt_porder = i ;
memcpy ( & opt_rc , rc , sizeof ( RiceContext ) ) ;
}
}
if ( opt_porder ! = pmax ) {
memcpy ( rc , & opt_rc , sizeof ( RiceContext ) ) ;
}
av_freep ( & udata ) ;
return opt_bits ;
}
static uint32_t calc_rice_params_fixed ( RiceContext * rc , int pmax , int32_t * data ,
int n , int pred_order , int bps )
{
uint32_t bits ;
bits = pred_order * bps + 6 ;
bits + = calc_rice_params ( rc , pmax , data , n , pred_order ) ;
return bits ;
}
static void encode_residual_verbatim ( int32_t * res , int32_t * smp , int n )
{
assert ( n > 0 ) ;
memcpy ( res , smp , n * sizeof ( int32_t ) ) ;
}
static void encode_residual_fixed ( int32_t * res , int32_t * smp , int n , int order )
{
int i ;
for ( i = 0 ; i < order ; i + + ) {
res [ i ] = smp [ i ] ;
}
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 ) {
for ( i = order ; i < n ; i + + )
res [ i ] = smp [ i ] - 2 * smp [ i - 1 ] + smp [ i - 2 ] ;
} else if ( order = = 3 ) {
for ( i = order ; i < n ; i + + )
res [ i ] = smp [ i ] - 3 * smp [ i - 1 ] + 3 * smp [ i - 2 ] - smp [ i - 3 ] ;
} else {
for ( i = order ; i < n ; i + + )
res [ i ] = smp [ i ] - 4 * smp [ i - 1 ] + 6 * smp [ i - 2 ] - 4 * smp [ i - 3 ] + smp [ i - 4 ] ;
}
}
static int get_max_p_order ( int max_porder , int n , int order )
{
int porder , max_parts ;
porder = max_porder ;
while ( porder > 0 ) {
max_parts = ( 1 < < porder ) ;
if ( ! ( n % max_parts ) & & ( n > max_parts * order ) ) {
break ;
}
porder - - ;
}
return porder ;
}
static int encode_residual ( FlacEncodeContext * ctx , int ch )
{
int i , opt_order , porder , max_porder , n ;
FlacFrame * frame ;
FlacSubframe * sub ;
uint32_t bits [ 5 ] ;
int32_t * res , * smp ;
frame = & ctx - > frame ;
sub = & frame - > subframes [ ch ] ;
res = sub - > residual ;
smp = sub - > samples ;
n = frame - > blocksize ;
/* CONSTANT */
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 sub - > obits ;
}
/* VERBATIM */
if ( n < 5 ) {
sub - > type = sub - > type_code = FLAC_SUBFRAME_VERBATIM ;
encode_residual_verbatim ( res , smp , n ) ;
return sub - > obits * n ;
}
max_porder = 3 ;
/* FIXED */
opt_order = 0 ;
bits [ 0 ] = UINT32_MAX ;
for ( i = 0 ; i < = 4 ; i + + ) {
encode_residual_fixed ( res , smp , n , i ) ;
porder = get_max_p_order ( max_porder , n , i ) ;
bits [ i ] = calc_rice_params_fixed ( & sub - > rc , porder , res , n , i , sub - > obits ) ;
if ( bits [ i ] < bits [ opt_order ] ) {
opt_order = i ;
}
}
sub - > order = opt_order ;
sub - > type = FLAC_SUBFRAME_FIXED ;
sub - > type_code = sub - > type | sub - > order ;
if ( sub - > order ! = 4 ) {
encode_residual_fixed ( res , smp , n , sub - > order ) ;
porder = get_max_p_order ( max_porder , n , sub - > order ) ;
calc_rice_params_fixed ( & sub - > rc , porder , res , n , sub - > order , sub - > obits ) ;
}
return bits [ sub - > order ] ;
}
static int encode_residual_v ( FlacEncodeContext * ctx , int ch )
{
int i , n ;
FlacFrame * frame ;
FlacSubframe * sub ;
int32_t * res , * smp ;
frame = & ctx - > frame ;
sub = & frame - > subframes [ ch ] ;
res = sub - > residual ;
smp = sub - > samples ;
n = frame - > blocksize ;
/* CONSTANT */
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 sub - > obits ;
}
/* VERBATIM */
sub - > type = sub - > type_code = FLAC_SUBFRAME_VERBATIM ;
encode_residual_verbatim ( res , smp , n ) ;
return sub - > obits * n ;
}
static int estimate_stereo_mode ( int32_t * left_ch , int32_t * right_ch , int n )
{
int i , best ;
int32_t lt , rt ;
uint64_t left , right , mid , side ;
uint64_t sum [ 4 ] ;
uint64_t score [ 4 ] ;
int k ;
/* calculate sum of squares for each channel */
left = right = mid = side = 0 ;
sum [ 0 ] = sum [ 1 ] = sum [ 2 ] = sum [ 3 ] = 0 ;
for ( 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 ] ;
mid + = ABS ( ( lt + rt ) > > 1 ) ;
side + = ABS ( lt - rt ) ;
left + = ABS ( lt ) ;
right + = ABS ( rt ) ;
sum [ 2 ] + = ABS ( ( lt + rt ) > > 1 ) ;
sum [ 3 ] + = ABS ( lt - rt ) ;
sum [ 0 ] + = ABS ( lt ) ;
sum [ 1 ] + = ABS ( rt ) ;
}
for ( i = 0 ; i < 4 ; i + + ) {
k = find_optimal_param ( 2 * sum [ i ] , n ) ;
sum [ i ] = rice_encode_count ( 2 * sum [ i ] , n , k ) ;
}
/* calculate score for each mode */
score [ 0 ] = left + right ;
score [ 1 ] = left + side ;
score [ 2 ] = right + side ;
score [ 3 ] = mid + side ;
score [ 0 ] = sum [ 0 ] + sum [ 1 ] ;
score [ 1 ] = sum [ 0 ] + sum [ 3 ] ;
score [ 2 ] = sum [ 1 ] + sum [ 3 ] ;
score [ 3 ] = sum [ 2 ] + sum [ 3 ] ;
/* return mode with lowest score */
best = 0 ;
@ -332,83 +595,14 @@ static void channel_decorrelation(FlacEncodeContext *ctx)
}
}
static void encode_residual_verbatim ( FlacEncodeContext * s , int ch )
{
FlacFrame * frame ;
FlacSubframe * sub ;
int32_t * res ;
int32_t * smp ;
int n ;
frame = & s - > frame ;
sub = & frame - > subframes [ ch ] ;
res = sub - > residual ;
smp = sub - > samples ;
n = frame - > blocksize ;
sub - > order = 0 ;
sub - > type = FLAC_SUBFRAME_VERBATIM ;
sub - > type_code = sub - > type ;
memcpy ( res , smp , n * sizeof ( int32_t ) ) ;
}
static void encode_residual_fixed ( int32_t * res , int32_t * smp , int n , int order )
{
int i ;
for ( i = 0 ; i < order ; i + + ) {
res [ i ] = smp [ i ] ;
}
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 ) {
for ( i = order ; i < n ; i + + )
res [ i ] = smp [ i ] - 2 * smp [ i - 1 ] + smp [ i - 2 ] ;
} else if ( order = = 3 ) {
for ( i = order ; i < n ; i + + )
res [ i ] = smp [ i ] - 3 * smp [ i - 1 ] + 3 * smp [ i - 2 ] - smp [ i - 3 ] ;
} else {
for ( i = order ; i < n ; i + + )
res [ i ] = smp [ i ] - 4 * smp [ i - 1 ] + 6 * smp [ i - 2 ] - 4 * smp [ i - 3 ] + smp [ i - 4 ] ;
}
}
static void encode_residual ( FlacEncodeContext * s , int ch )
{
FlacFrame * frame ;
FlacSubframe * sub ;
int32_t * res ;
int32_t * smp ;
int n ;
frame = & s - > frame ;
sub = & frame - > subframes [ ch ] ;
res = sub - > residual ;
smp = sub - > samples ;
n = frame - > blocksize ;
sub - > order = 2 ;
sub - > type = FLAC_SUBFRAME_FIXED ;
sub - > type_code = sub - > type | sub - > order ;
encode_residual_fixed ( res , smp , n , sub - > order ) ;
}
static void
put_sbits ( PutBitContext * pb , int bits , int32_t val )
static void put_sbits ( PutBitContext * pb , int bits , int32_t val )
{
assert ( bits > = 0 & & bits < = 31 ) ;
put_bits ( pb , bits , val & ( ( 1 < < bits ) - 1 ) ) ;
}
static void
write_utf8 ( PutBitContext * pb , uint32_t val )
static void write_utf8 ( PutBitContext * pb , uint32_t val )
{
int bytes , shift ;
@ -426,8 +620,7 @@ write_utf8(PutBitContext *pb, uint32_t val)
}
}
static void
output_frame_header ( FlacEncodeContext * s )
static void output_frame_header ( FlacEncodeContext * s )
{
FlacFrame * frame ;
int crc ;
@ -460,6 +653,16 @@ output_frame_header(FlacEncodeContext *s)
put_bits ( & s - > pb , 8 , crc ) ;
}
static void output_subframe_constant ( FlacEncodeContext * s , int ch )
{
FlacSubframe * sub ;
int32_t res ;
sub = & s - > frame . subframes [ ch ] ;
res = sub - > residual [ 0 ] ;
put_sbits ( & s - > pb , sub - > obits , res ) ;
}
static void output_subframe_verbatim ( FlacEncodeContext * s , int ch )
{
int i ;
@ -476,43 +679,42 @@ static void output_subframe_verbatim(FlacEncodeContext *s, int ch)
}
}
static void
output_residual ( FlacEncodeContext * ctx , int ch )
static void output_residual ( FlacEncodeContext * ctx , int ch )
{
int i , j , p ;
int i , j , p , n , parts ;
int k , porder , psize , res_cnt ;
FlacFrame * frame ;
FlacSubframe * sub ;
int32_t * res ;
frame = & ctx - > frame ;
sub = & frame - > subframes [ ch ] ;
res = sub - > residual ;
n = frame - > blocksize ;
/* rice-encoded block */
put_bits ( & ctx - > pb , 2 , 0 ) ;
/* partition order */
porder = 0 ;
psize = frame - > blocksize ;
//porder = sub->rc.porder;
//psize = frame->blocksize >> porder;
porder = sub - > rc . porder ;
psize = n > > porder ;
parts = ( 1 < < porder ) ;
put_bits ( & ctx - > pb , 4 , porder ) ;
res_cnt = psize - sub - > order ;
/* residual */
j = sub - > order ;
for ( p = 0 ; p < ( 1 < < porder ) ; p + + ) {
//k = sub->rc.params[p];
k = 9 ;
for ( p = 0 ; p < parts ; p + + ) {
k = sub - > rc . params [ p ] ;
put_bits ( & ctx - > pb , 4 , k ) ;
if ( p = = 1 ) res_cnt = psize ;
for ( i = 0 ; i < res_cnt & & j < frame - > blocksize ; i + + , j + + ) {
set_sr_golomb_flac ( & ctx - > pb , sub - > residual [ j ] , k , INT32_MAX , 0 ) ;
for ( i = 0 ; i < res_cnt & & j < n ; i + + , j + + ) {
set_sr_golomb_flac ( & ctx - > pb , res [ j ] , k , INT32_MAX , 0 ) ;
}
}
}
static void
output_subframe_fixed ( FlacEncodeContext * ctx , int ch )
static void output_subframe_fixed ( FlacEncodeContext * ctx , int ch )
{
int i ;
FlacFrame * frame ;
@ -547,9 +749,11 @@ static void output_subframes(FlacEncodeContext *s)
put_bits ( & s - > pb , 1 , 0 ) ; /* no wasted bits */
/* subframe */
if ( sub - > type = = FLAC_SUBFRAME_VERBATIM ) {
if ( sub - > type = = FLAC_SUBFRAME_CONSTANT ) {
output_subframe_constant ( s , ch ) ;
} else if ( sub - > type = = FLAC_SUBFRAME_VERBATIM ) {
output_subframe_verbatim ( s , ch ) ;
} else {
} else if ( sub - > type = = FLAC_SUBFRAME_FIXED ) {
output_subframe_fixed ( s , ch ) ;
}
}
@ -593,7 +797,7 @@ static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame,
if ( out_bytes > s - > max_framesize | | out_bytes > = buf_size ) {
/* frame too large. use verbatim mode */
for ( ch = 0 ; ch < s - > channels ; ch + + ) {
encode_residual_verbatim ( s , ch ) ;
encode_residual_v ( s , ch ) ;
}
init_put_bits ( & s - > pb , frame , buf_size ) ;
output_frame_header ( s ) ;