/*
* Opus encoder
* Copyright ( c ) 2017 Rostislav Pehlivanov < atomnuker @ gmail . com >
*
* This file is part of FFmpeg .
*
* FFmpeg is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* FFmpeg is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
# include "opusenc.h"
# include "opus_pvq.h"
# include "opusenc_psy.h"
# include "opustab.h"
# include "libavutil/float_dsp.h"
# include "libavutil/opt.h"
# include "internal.h"
# include "bytestream.h"
# include "audio_frame_queue.h"
typedef struct OpusEncContext {
AVClass * av_class ;
OpusEncOptions options ;
OpusPsyContext psyctx ;
AVCodecContext * avctx ;
AudioFrameQueue afq ;
AVFloatDSPContext * dsp ;
MDCT15Context * mdct [ CELT_BLOCK_NB ] ;
CeltPVQ * pvq ;
struct FFBufQueue bufqueue ;
uint8_t enc_id [ 64 ] ;
int enc_id_bits ;
OpusPacketInfo packet ;
int channels ;
CeltFrame * frame ;
OpusRangeCoder * rc ;
/* Actual energy the decoder will have */
float last_quantized_energy [ OPUS_MAX_CHANNELS ] [ CELT_MAX_BANDS ] ;
DECLARE_ALIGNED ( 32 , float , scratch ) [ 2048 ] ;
} OpusEncContext ;
static void opus_write_extradata ( AVCodecContext * avctx )
{
uint8_t * bs = avctx - > extradata ;
bytestream_put_buffer ( & bs , " OpusHead " , 8 ) ;
bytestream_put_byte ( & bs , 0x1 ) ;
bytestream_put_byte ( & bs , avctx - > channels ) ;
bytestream_put_le16 ( & bs , avctx - > initial_padding ) ;
bytestream_put_le32 ( & bs , avctx - > sample_rate ) ;
bytestream_put_le16 ( & bs , 0x0 ) ;
bytestream_put_byte ( & bs , 0x0 ) ; /* Default layout */
}
static int opus_gen_toc ( OpusEncContext * s , uint8_t * toc , int * size , int * fsize_needed )
{
int i , tmp = 0x0 , extended_toc = 0 ;
static const int toc_cfg [ ] [ OPUS_MODE_NB ] [ OPUS_BANDWITH_NB ] = {
/* Silk Hybrid Celt Layer */
/* NB MB WB SWB FB NB MB WB SWB FB NB MB WB SWB FB Bandwidth */
{ { 0 , 0 , 0 , 0 , 0 } , { 0 , 0 , 0 , 0 , 0 } , { 17 , 0 , 21 , 25 , 29 } } , /* 2.5 ms */
{ { 0 , 0 , 0 , 0 , 0 } , { 0 , 0 , 0 , 0 , 0 } , { 18 , 0 , 22 , 26 , 30 } } , /* 5 ms */
{ { 1 , 5 , 9 , 0 , 0 } , { 0 , 0 , 0 , 13 , 15 } , { 19 , 0 , 23 , 27 , 31 } } , /* 10 ms */
{ { 2 , 6 , 10 , 0 , 0 } , { 0 , 0 , 0 , 14 , 16 } , { 20 , 0 , 24 , 28 , 32 } } , /* 20 ms */
{ { 3 , 7 , 11 , 0 , 0 } , { 0 , 0 , 0 , 0 , 0 } , { 0 , 0 , 0 , 0 , 0 } } , /* 40 ms */
{ { 4 , 8 , 12 , 0 , 0 } , { 0 , 0 , 0 , 0 , 0 } , { 0 , 0 , 0 , 0 , 0 } } , /* 60 ms */
} ;
int cfg = toc_cfg [ s - > packet . framesize ] [ s - > packet . mode ] [ s - > packet . bandwidth ] ;
* fsize_needed = 0 ;
if ( ! cfg )
return 1 ;
if ( s - > packet . frames = = 2 ) { /* 2 packets */
if ( s - > frame [ 0 ] . framebits = = s - > frame [ 1 ] . framebits ) { /* same size */
tmp = 0x1 ;
} else { /* different size */
tmp = 0x2 ;
* fsize_needed = 1 ; /* put frame sizes in the packet */
}
} else if ( s - > packet . frames > 2 ) {
tmp = 0x3 ;
extended_toc = 1 ;
}
tmp | = ( s - > channels > 1 ) < < 2 ; /* Stereo or mono */
tmp | = ( cfg - 1 ) < < 3 ; /* codec configuration */
* toc + + = tmp ;
if ( extended_toc ) {
for ( i = 0 ; i < ( s - > packet . frames - 1 ) ; i + + )
* fsize_needed | = ( s - > frame [ i ] . framebits ! = s - > frame [ i + 1 ] . framebits ) ;
tmp = ( * fsize_needed ) < < 7 ; /* vbr flag */
tmp | = ( 0 ) < < 6 ; /* padding flag */
tmp | = s - > packet . frames ;
* toc + + = tmp ;
}
* size = 1 + extended_toc ;
return 0 ;
}
static void celt_frame_setup_input ( OpusEncContext * s , CeltFrame * f )
{
int sf , ch ;
AVFrame * cur = NULL ;
const int subframesize = s - > avctx - > frame_size ;
int subframes = OPUS_BLOCK_SIZE ( s - > packet . framesize ) / subframesize ;
cur = ff_bufqueue_get ( & s - > bufqueue ) ;
for ( ch = 0 ; ch < f - > channels ; ch + + ) {
CeltBlock * b = & f - > block [ ch ] ;
const void * input = cur - > extended_data [ ch ] ;
size_t bps = av_get_bytes_per_sample ( cur - > format ) ;
memcpy ( b - > overlap , input , bps * cur - > nb_samples ) ;
}
av_frame_free ( & cur ) ;
for ( sf = 0 ; sf < subframes ; sf + + ) {
if ( sf ! = ( subframes - 1 ) )
cur = ff_bufqueue_get ( & s - > bufqueue ) ;
else
cur = ff_bufqueue_peek ( & s - > bufqueue , 0 ) ;
for ( ch = 0 ; ch < f - > channels ; ch + + ) {
CeltBlock * b = & f - > block [ ch ] ;
const void * input = cur - > extended_data [ ch ] ;
const size_t bps = av_get_bytes_per_sample ( cur - > format ) ;
const size_t left = ( subframesize - cur - > nb_samples ) * bps ;
const size_t len = FFMIN ( subframesize , cur - > nb_samples ) * bps ;
memcpy ( & b - > samples [ sf * subframesize ] , input , len ) ;
memset ( & b - > samples [ cur - > nb_samples ] , 0 , left ) ;
}
/* Last frame isn't popped off and freed yet - we need it for overlap */
if ( sf ! = ( subframes - 1 ) )
av_frame_free ( & cur ) ;
}
}
/* Apply the pre emphasis filter */
static void celt_apply_preemph_filter ( OpusEncContext * s , CeltFrame * f )
{
int i , sf , ch ;
const int subframesize = s - > avctx - > frame_size ;
const int subframes = OPUS_BLOCK_SIZE ( s - > packet . framesize ) / subframesize ;
/* Filter overlap */
for ( ch = 0 ; ch < f - > channels ; ch + + ) {
CeltBlock * b = & f - > block [ ch ] ;
float m = b - > emph_coeff ;
for ( i = 0 ; i < CELT_OVERLAP ; i + + ) {
float sample = b - > overlap [ i ] ;
b - > overlap [ i ] = sample - m ;
m = sample * CELT_EMPH_COEFF ;
}
b - > emph_coeff = m ;
}
/* Filter the samples but do not update the last subframe's coeff - overlap ^^^ */
for ( sf = 0 ; sf < subframes ; sf + + ) {
for ( ch = 0 ; ch < f - > channels ; ch + + ) {
CeltBlock * b = & f - > block [ ch ] ;
float m = b - > emph_coeff ;
for ( i = 0 ; i < subframesize ; i + + ) {
float sample = b - > samples [ sf * subframesize + i ] ;
b - > samples [ sf * subframesize + i ] = sample - m ;
m = sample * CELT_EMPH_COEFF ;
}
if ( sf ! = ( subframes - 1 ) )
b - > emph_coeff = m ;
}
}
}
/* Create the window and do the mdct */
static void celt_frame_mdct ( OpusEncContext * s , CeltFrame * f )
{
int i , j , t , ch ;
float * win = s - > scratch , * temp = s - > scratch + 1920 ;
if ( f - > transient ) {
for ( ch = 0 ; ch < f - > channels ; ch + + ) {
CeltBlock * b = & f - > block [ ch ] ;
float * src1 = b - > overlap ;
for ( t = 0 ; t < f - > blocks ; t + + ) {
float * src2 = & b - > samples [ CELT_OVERLAP * t ] ;
s - > dsp - > vector_fmul ( win , src1 , ff_celt_window , 128 ) ;
s - > dsp - > vector_fmul_reverse ( & win [ CELT_OVERLAP ] , src2 ,
ff_celt_window - 8 , 128 ) ;
src1 = src2 ;
s - > mdct [ 0 ] - > mdct ( s - > mdct [ 0 ] , b - > coeffs + t , win , f - > blocks ) ;
}
}
} else {
int blk_len = OPUS_BLOCK_SIZE ( f - > size ) , wlen = OPUS_BLOCK_SIZE ( f - > size + 1 ) ;
int rwin = blk_len - CELT_OVERLAP , lap_dst = ( wlen - blk_len - CELT_OVERLAP ) > > 1 ;
memset ( win , 0 , wlen * sizeof ( float ) ) ;
for ( ch = 0 ; ch < f - > channels ; ch + + ) {
CeltBlock * b = & f - > block [ ch ] ;
/* Overlap */
s - > dsp - > vector_fmul ( temp , b - > overlap , ff_celt_window , 128 ) ;
memcpy ( win + lap_dst , temp , CELT_OVERLAP * sizeof ( float ) ) ;
/* Samples, flat top window */
memcpy ( & win [ lap_dst + CELT_OVERLAP ] , b - > samples , rwin * sizeof ( float ) ) ;
/* Samples, windowed */
s - > dsp - > vector_fmul_reverse ( temp , b - > samples + rwin ,
ff_celt_window - 8 , 128 ) ;
memcpy ( win + lap_dst + blk_len , temp , CELT_OVERLAP * sizeof ( float ) ) ;
s - > mdct [ f - > size ] - > mdct ( s - > mdct [ f - > size ] , b - > coeffs , win , 1 ) ;
}
}
for ( ch = 0 ; ch < f - > channels ; ch + + ) {
CeltBlock * block = & f - > block [ ch ] ;
for ( i = 0 ; i < CELT_MAX_BANDS ; i + + ) {
float ener = 0.0f ;
int band_offset = ff_celt_freq_bands [ i ] < < f - > size ;
int band_size = ff_celt_freq_range [ i ] < < f - > size ;
float * coeffs = & block - > coeffs [ band_offset ] ;
for ( j = 0 ; j < band_size ; j + + )
ener + = coeffs [ j ] * coeffs [ j ] ;
block - > lin_energy [ i ] = sqrtf ( ener ) + FLT_EPSILON ;
ener = 1.0f / block - > lin_energy [ i ] ;
for ( j = 0 ; j < band_size ; j + + )
coeffs [ j ] * = ener ;
block - > energy [ i ] = log2f ( block - > lin_energy [ i ] ) - ff_celt_mean_energy [ i ] ;
/* CELT_ENERGY_SILENCE is what the decoder uses and its not -infinity */
block - > energy [ i ] = FFMAX ( block - > energy [ i ] , CELT_ENERGY_SILENCE ) ;
}
}
}
static void celt_enc_tf ( OpusRangeCoder * rc , CeltFrame * f )
{
int i , tf_select = 0 , diff = 0 , tf_changed = 0 , tf_select_needed ;
int bits = f - > transient ? 2 : 4 ;
tf_select_needed = ( ( f - > size & & ( opus_rc_tell ( rc ) + bits + 1 ) < = f - > framebits ) ) ;
for ( i = f - > start_band ; i < f - > end_band ; i + + ) {
if ( ( opus_rc_tell ( rc ) + bits + tf_select_needed ) < = f - > framebits ) {
const int tbit = ( diff ^ 1 ) = = f - > tf_change [ i ] ;
ff_opus_rc_enc_log ( rc , tbit , bits ) ;
diff ^ = tbit ;
tf_changed | = diff ;
}
bits = f - > transient ? 4 : 5 ;
}
if ( tf_select_needed & & ff_celt_tf_select [ f - > size ] [ f - > transient ] [ 0 ] [ tf_changed ] ! =
ff_celt_tf_select [ f - > size ] [ f - > transient ] [ 1 ] [ tf_changed ] ) {
ff_opus_rc_enc_log ( rc , f - > tf_select , 1 ) ;
tf_select = f - > tf_select ;
}
for ( i = f - > start_band ; i < f - > end_band ; i + + )
f - > tf_change [ i ] = ff_celt_tf_select [ f - > size ] [ f - > transient ] [ tf_select ] [ f - > tf_change [ i ] ] ;
}
void ff_celt_enc_bitalloc ( OpusRangeCoder * rc , CeltFrame * f )
{
int i , j , low , high , total , done , bandbits , remaining , tbits_8ths ;
int skip_startband = f - > start_band ;
int skip_bit = 0 ;
int intensitystereo_bit = 0 ;
int dualstereo_bit = 0 ;
int dynalloc = 6 ;
int extrabits = 0 ;
int * cap = f - > caps ;
int boost [ CELT_MAX_BANDS ] ;
int trim_offset [ CELT_MAX_BANDS ] ;
int threshold [ CELT_MAX_BANDS ] ;
int bits1 [ CELT_MAX_BANDS ] ;
int bits2 [ CELT_MAX_BANDS ] ;
/* Tell the spread to the decoder */
if ( opus_rc_tell ( rc ) + 4 < = f - > framebits )
ff_opus_rc_enc_cdf ( rc , f - > spread , ff_celt_model_spread ) ;
else
f - > spread = CELT_SPREAD_NORMAL ;
/* Generate static allocation caps */
for ( i = 0 ; i < CELT_MAX_BANDS ; i + + ) {
cap [ i ] = ( ff_celt_static_caps [ f - > size ] [ f - > channels - 1 ] [ i ] + 64 )
* ff_celt_freq_range [ i ] < < ( f - > channels - 1 ) < < f - > size > > 2 ;
}
/* Band boosts */
tbits_8ths = f - > framebits < < 3 ;
for ( i = f - > start_band ; i < f - > end_band ; i + + ) {
int quanta , b_dynalloc , boost_amount = f - > alloc_boost [ i ] ;
boost [ i ] = 0 ;
quanta = ff_celt_freq_range [ i ] < < ( f - > channels - 1 ) < < f - > size ;
quanta = FFMIN ( quanta < < 3 , FFMAX ( 6 < < 3 , quanta ) ) ;
b_dynalloc = dynalloc ;
while ( opus_rc_tell_frac ( rc ) + ( b_dynalloc < < 3 ) < tbits_8ths & & boost [ i ] < cap [ i ] ) {
int is_boost = boost_amount - - ;
ff_opus_rc_enc_log ( rc , is_boost , b_dynalloc ) ;
if ( ! is_boost )
break ;
boost [ i ] + = quanta ;
tbits_8ths - = quanta ;
b_dynalloc = 1 ;
}
if ( boost [ i ] )
dynalloc = FFMAX ( 2 , dynalloc - 1 ) ;
}
/* Put allocation trim */
if ( opus_rc_tell_frac ( rc ) + ( 6 < < 3 ) < = tbits_8ths )
ff_opus_rc_enc_cdf ( rc , f - > alloc_trim , ff_celt_model_alloc_trim ) ;
/* Anti-collapse bit reservation */
tbits_8ths = ( f - > framebits < < 3 ) - opus_rc_tell_frac ( rc ) - 1 ;
f - > anticollapse_needed = 0 ;
if ( f - > transient & & f - > size > = 2 & & tbits_8ths > = ( ( f - > size + 2 ) < < 3 ) )
f - > anticollapse_needed = 1 < < 3 ;
tbits_8ths - = f - > anticollapse_needed ;
/* Band skip bit reservation */
if ( tbits_8ths > = 1 < < 3 )
skip_bit = 1 < < 3 ;
tbits_8ths - = skip_bit ;
/* Intensity/dual stereo bit reservation */
if ( f - > channels = = 2 ) {
intensitystereo_bit = ff_celt_log2_frac [ f - > end_band - f - > start_band ] ;
if ( intensitystereo_bit < = tbits_8ths ) {
tbits_8ths - = intensitystereo_bit ;
if ( tbits_8ths > = 1 < < 3 ) {
dualstereo_bit = 1 < < 3 ;
tbits_8ths - = 1 < < 3 ;
}
} else {
intensitystereo_bit = 0 ;
}
}
/* Trim offsets */
for ( i = f - > start_band ; i < f - > end_band ; i + + ) {
int trim = f - > alloc_trim - 5 - f - > size ;
int band = ff_celt_freq_range [ i ] * ( f - > end_band - i - 1 ) ;
int duration = f - > size + 3 ;
int scale = duration + f - > channels - 1 ;
/* PVQ minimum allocation threshold, below this value the band is
* skipped */
threshold [ i ] = FFMAX ( 3 * ff_celt_freq_range [ i ] < < duration > > 4 ,
f - > channels < < 3 ) ;
trim_offset [ i ] = trim * ( band < < scale ) > > 6 ;
if ( ff_celt_freq_range [ i ] < < f - > size = = 1 )
trim_offset [ i ] - = f - > channels < < 3 ;
}
/* Bisection */
low = 1 ;
high = CELT_VECTORS - 1 ;
while ( low < = high ) {
int center = ( low + high ) > > 1 ;
done = total = 0 ;
for ( i = f - > end_band - 1 ; i > = f - > start_band ; i - - ) {
bandbits = ff_celt_freq_range [ i ] * ff_celt_static_alloc [ center ] [ i ]
< < ( f - > channels - 1 ) < < f - > size > > 2 ;
if ( bandbits )
bandbits = FFMAX ( 0 , bandbits + trim_offset [ i ] ) ;
bandbits + = boost [ i ] ;
if ( bandbits > = threshold [ i ] | | done ) {
done = 1 ;
total + = FFMIN ( bandbits , cap [ i ] ) ;
} else if ( bandbits > = f - > channels < < 3 )
total + = f - > channels < < 3 ;
}
if ( total > tbits_8ths )
high = center - 1 ;
else
low = center + 1 ;
}
high = low - - ;
/* Bisection */
for ( i = f - > start_band ; i < f - > end_band ; i + + ) {
bits1 [ i ] = ff_celt_freq_range [ i ] * ff_celt_static_alloc [ low ] [ i ]
< < ( f - > channels - 1 ) < < f - > size > > 2 ;
bits2 [ i ] = high > = CELT_VECTORS ? cap [ i ] :
ff_celt_freq_range [ i ] * ff_celt_static_alloc [ high ] [ i ]
< < ( f - > channels - 1 ) < < f - > size > > 2 ;
if ( bits1 [ i ] )
bits1 [ i ] = FFMAX ( 0 , bits1 [ i ] + trim_offset [ i ] ) ;
if ( bits2 [ i ] )
bits2 [ i ] = FFMAX ( 0 , bits2 [ i ] + trim_offset [ i ] ) ;
if ( low )
bits1 [ i ] + = boost [ i ] ;
bits2 [ i ] + = boost [ i ] ;
if ( boost [ i ] )
skip_startband = i ;
bits2 [ i ] = FFMAX ( 0 , bits2 [ i ] - bits1 [ i ] ) ;
}
/* Bisection */
low = 0 ;
high = 1 < < CELT_ALLOC_STEPS ;
for ( i = 0 ; i < CELT_ALLOC_STEPS ; i + + ) {
int center = ( low + high ) > > 1 ;
done = total = 0 ;
for ( j = f - > end_band - 1 ; j > = f - > start_band ; j - - ) {
bandbits = bits1 [ j ] + ( center * bits2 [ j ] > > CELT_ALLOC_STEPS ) ;
if ( bandbits > = threshold [ j ] | | done ) {
done = 1 ;
total + = FFMIN ( bandbits , cap [ j ] ) ;
} else if ( bandbits > = f - > channels < < 3 )
total + = f - > channels < < 3 ;
}
if ( total > tbits_8ths )
high = center ;
else
low = center ;
}
/* Bisection */
done = total = 0 ;
for ( i = f - > end_band - 1 ; i > = f - > start_band ; i - - ) {
bandbits = bits1 [ i ] + ( low * bits2 [ i ] > > CELT_ALLOC_STEPS ) ;
if ( bandbits > = threshold [ i ] | | done )
done = 1 ;
else
bandbits = ( bandbits > = f - > channels < < 3 ) ?
f - > channels < < 3 : 0 ;
bandbits = FFMIN ( bandbits , cap [ i ] ) ;
f - > pulses [ i ] = bandbits ;
total + = bandbits ;
}
/* Band skipping */
for ( f - > coded_bands = f - > end_band ; ; f - > coded_bands - - ) {
int allocation ;
j = f - > coded_bands - 1 ;
if ( j = = skip_startband ) {
/* all remaining bands are not skipped */
tbits_8ths + = skip_bit ;
break ;
}
/* determine the number of bits available for coding "do not skip" markers */
remaining = tbits_8ths - total ;
bandbits = remaining / ( ff_celt_freq_bands [ j + 1 ] - ff_celt_freq_bands [ f - > start_band ] ) ;
remaining - = bandbits * ( ff_celt_freq_bands [ j + 1 ] - ff_celt_freq_bands [ f - > start_band ] ) ;
allocation = f - > pulses [ j ] + bandbits * ff_celt_freq_range [ j ]
+ FFMAX ( 0 , remaining - ( ff_celt_freq_bands [ j ] - ff_celt_freq_bands [ f - > start_band ] ) ) ;
/* a "do not skip" marker is only coded if the allocation is
above the chosen threshold */
if ( allocation > = FFMAX ( threshold [ j ] , ( f - > channels + 1 ) < < 3 ) ) {
const int do_not_skip = f - > coded_bands < = f - > skip_band_floor ;
ff_opus_rc_enc_log ( rc , do_not_skip , 1 ) ;
if ( do_not_skip )
break ;
total + = 1 < < 3 ;
allocation - = 1 < < 3 ;
}
/* the band is skipped, so reclaim its bits */
total - = f - > pulses [ j ] ;
if ( intensitystereo_bit ) {
total - = intensitystereo_bit ;
intensitystereo_bit = ff_celt_log2_frac [ j - f - > start_band ] ;
total + = intensitystereo_bit ;
}
total + = f - > pulses [ j ] = ( allocation > = f - > channels < < 3 ) ? f - > channels < < 3 : 0 ;
}
/* Encode stereo flags */
if ( intensitystereo_bit ) {
f - > intensity_stereo = FFMIN ( f - > intensity_stereo , f - > coded_bands ) ;
ff_opus_rc_enc_uint ( rc , f - > intensity_stereo , f - > coded_bands + 1 - f - > start_band ) ;
}
if ( f - > intensity_stereo < = f - > start_band )
tbits_8ths + = dualstereo_bit ; /* no intensity stereo means no dual stereo */
else if ( dualstereo_bit )
ff_opus_rc_enc_log ( rc , f - > dual_stereo , 1 ) ;
/* Supply the remaining bits in this frame to lower bands */
remaining = tbits_8ths - total ;
bandbits = remaining / ( ff_celt_freq_bands [ f - > coded_bands ] - ff_celt_freq_bands [ f - > start_band ] ) ;
remaining - = bandbits * ( ff_celt_freq_bands [ f - > coded_bands ] - ff_celt_freq_bands [ f - > start_band ] ) ;
for ( i = f - > start_band ; i < f - > coded_bands ; i + + ) {
int bits = FFMIN ( remaining , ff_celt_freq_range [ i ] ) ;
f - > pulses [ i ] + = bits + bandbits * ff_celt_freq_range [ i ] ;
remaining - = bits ;
}
/* Finally determine the allocation */
for ( i = f - > start_band ; i < f - > coded_bands ; i + + ) {
int N = ff_celt_freq_range [ i ] < < f - > size ;
int prev_extra = extrabits ;
f - > pulses [ i ] + = extrabits ;
if ( N > 1 ) {
int dof ; // degrees of freedom
int temp ; // dof * channels * log(dof)
int offset ; // fine energy quantization offset, i.e.
// extra bits assigned over the standard
// totalbits/dof
int fine_bits , max_bits ;
extrabits = FFMAX ( 0 , f - > pulses [ i ] - cap [ i ] ) ;
f - > pulses [ i ] - = extrabits ;
/* intensity stereo makes use of an extra degree of freedom */
dof = N * f - > channels + ( f - > channels = = 2 & & N > 2 & & ! f - > dual_stereo & & i < f - > intensity_stereo ) ;
temp = dof * ( ff_celt_log_freq_range [ i ] + ( f - > size < < 3 ) ) ;
offset = ( temp > > 1 ) - dof * CELT_FINE_OFFSET ;
if ( N = = 2 ) /* dof=2 is the only case that doesn't fit the model */
offset + = dof < < 1 ;
/* grant an additional bias for the first and second pulses */
if ( f - > pulses [ i ] + offset < 2 * ( dof < < 3 ) )
offset + = temp > > 2 ;
else if ( f - > pulses [ i ] + offset < 3 * ( dof < < 3 ) )
offset + = temp > > 3 ;
fine_bits = ( f - > pulses [ i ] + offset + ( dof < < 2 ) ) / ( dof < < 3 ) ;
max_bits = FFMIN ( ( f - > pulses [ i ] > > 3 ) > > ( f - > channels - 1 ) , CELT_MAX_FINE_BITS ) ;
max_bits = FFMAX ( max_bits , 0 ) ;
f - > fine_bits [ i ] = av_clip ( fine_bits , 0 , max_bits ) ;
/* if fine_bits was rounded down or capped,
give priority for the final fine energy pass */
f - > fine_priority [ i ] = ( f - > fine_bits [ i ] * ( dof < < 3 ) > = f - > pulses [ i ] + offset ) ;
/* the remaining bits are assigned to PVQ */
f - > pulses [ i ] - = f - > fine_bits [ i ] < < ( f - > channels - 1 ) < < 3 ;
} else {
/* all bits go to fine energy except for the sign bit */
extrabits = FFMAX ( 0 , f - > pulses [ i ] - ( f - > channels < < 3 ) ) ;
f - > pulses [ i ] - = extrabits ;
f - > fine_bits [ i ] = 0 ;
f - > fine_priority [ i ] = 1 ;
}
/* hand back a limited number of extra fine energy bits to this band */
if ( extrabits > 0 ) {
int fineextra = FFMIN ( extrabits > > ( f - > channels + 2 ) ,
CELT_MAX_FINE_BITS - f - > fine_bits [ i ] ) ;
f - > fine_bits [ i ] + = fineextra ;
fineextra < < = f - > channels + 2 ;
f - > fine_priority [ i ] = ( fineextra > = extrabits - prev_extra ) ;
extrabits - = fineextra ;
}
}
f - > remaining = extrabits ;
/* skipped bands dedicate all of their bits for fine energy */
for ( ; i < f - > end_band ; i + + ) {
f - > fine_bits [ i ] = f - > pulses [ i ] > > ( f - > channels - 1 ) > > 3 ;
f - > pulses [ i ] = 0 ;
f - > fine_priority [ i ] = f - > fine_bits [ i ] < 1 ;
}
}
static void celt_enc_quant_pfilter ( OpusRangeCoder * rc , CeltFrame * f )
{
float gain = f - > pf_gain ;
int i , txval , octave = f - > pf_octave , period = f - > pf_period , tapset = f - > pf_tapset ;
ff_opus_rc_enc_log ( rc , f - > pfilter , 1 ) ;
if ( ! f - > pfilter )
return ;
/* Octave */
txval = FFMIN ( octave , 6 ) ;
ff_opus_rc_enc_uint ( rc , txval , 6 ) ;
octave = txval ;
/* Period */
txval = av_clip ( period - ( 16 < < octave ) + 1 , 0 , ( 1 < < ( 4 + octave ) ) - 1 ) ;
ff_opus_rc_put_raw ( rc , period , 4 + octave ) ;
period = txval + ( 16 < < octave ) - 1 ;
/* Gain */
txval = FFMIN ( ( ( int ) ( gain / 0.09375f ) ) - 1 , 7 ) ;
ff_opus_rc_put_raw ( rc , txval , 3 ) ;
gain = 0.09375f * ( txval + 1 ) ;
/* Tapset */
if ( ( opus_rc_tell ( rc ) + 2 ) < = f - > framebits )
ff_opus_rc_enc_cdf ( rc , tapset , ff_celt_model_tapset ) ;
else
tapset = 0 ;
/* Finally create the coeffs */
for ( i = 0 ; i < 2 ; i + + ) {
CeltBlock * block = & f - > block [ i ] ;
block - > pf_period_new = FFMAX ( period , CELT_POSTFILTER_MINPERIOD ) ;
block - > pf_gains_new [ 0 ] = gain * ff_celt_postfilter_taps [ tapset ] [ 0 ] ;
block - > pf_gains_new [ 1 ] = gain * ff_celt_postfilter_taps [ tapset ] [ 1 ] ;
block - > pf_gains_new [ 2 ] = gain * ff_celt_postfilter_taps [ tapset ] [ 2 ] ;
}
}
static void exp_quant_coarse ( OpusRangeCoder * rc , CeltFrame * f ,
float last_energy [ ] [ CELT_MAX_BANDS ] , int intra )
{
int i , ch ;
float alpha , beta , prev [ 2 ] = { 0 , 0 } ;
const uint8_t * pmod = ff_celt_coarse_energy_dist [ f - > size ] [ intra ] ;
/* Inter is really just differential coding */
if ( opus_rc_tell ( rc ) + 3 < = f - > framebits )
ff_opus_rc_enc_log ( rc , intra , 3 ) ;
else
intra = 0 ;
if ( intra ) {
alpha = 0.0f ;
beta = 1.0f - ( 4915.0f / 32768.0f ) ;
} else {
alpha = ff_celt_alpha_coef [ f - > size ] ;
beta = ff_celt_beta_coef [ f - > size ] ;
}
for ( i = f - > start_band ; i < f - > end_band ; i + + ) {
for ( ch = 0 ; ch < f - > channels ; ch + + ) {
CeltBlock * block = & f - > block [ ch ] ;
const int left = f - > framebits - opus_rc_tell ( rc ) ;
const float last = FFMAX ( - 9.0f , last_energy [ ch ] [ i ] ) ;
float diff = block - > energy [ i ] - prev [ ch ] - last * alpha ;
int q_en = lrintf ( diff ) ;
if ( left > = 15 ) {
ff_opus_rc_enc_laplace ( rc , & q_en , pmod [ i < < 1 ] < < 7 , pmod [ ( i < < 1 ) + 1 ] < < 6 ) ;
} else if ( left > = 2 ) {
q_en = av_clip ( q_en , - 1 , 1 ) ;
ff_opus_rc_enc_cdf ( rc , 2 * q_en + 3 * ( q_en < 0 ) , ff_celt_model_energy_small ) ;
} else if ( left > = 1 ) {
q_en = av_clip ( q_en , - 1 , 0 ) ;
ff_opus_rc_enc_log ( rc , ( q_en & 1 ) , 1 ) ;
} else q_en = - 1 ;
block - > error_energy [ i ] = q_en - diff ;
prev [ ch ] + = beta * q_en ;
}
}
}
static void celt_quant_coarse ( OpusRangeCoder * rc , CeltFrame * f ,
float last_energy [ ] [ CELT_MAX_BANDS ] )
{
uint32_t inter , intra ;
OPUS_RC_CHECKPOINT_SPAWN ( rc ) ;
exp_quant_coarse ( rc , f , last_energy , 1 ) ;
intra = OPUS_RC_CHECKPOINT_BITS ( rc ) ;
OPUS_RC_CHECKPOINT_ROLLBACK ( rc ) ;
exp_quant_coarse ( rc , f , last_energy , 0 ) ;
inter = OPUS_RC_CHECKPOINT_BITS ( rc ) ;
if ( inter > intra ) { /* Unlikely */
OPUS_RC_CHECKPOINT_ROLLBACK ( rc ) ;
exp_quant_coarse ( rc , f , last_energy , 1 ) ;
}
}
static void celt_quant_fine ( OpusRangeCoder * rc , CeltFrame * f )
{
int i , ch ;
for ( i = f - > start_band ; i < f - > end_band ; i + + ) {
if ( ! f - > fine_bits [ i ] )
continue ;
for ( ch = 0 ; ch < f - > channels ; ch + + ) {
CeltBlock * block = & f - > block [ ch ] ;
int quant , lim = ( 1 < < f - > fine_bits [ i ] ) ;
float offset , diff = 0.5f - block - > error_energy [ i ] ;
quant = av_clip ( floor ( diff * lim ) , 0 , lim - 1 ) ;
ff_opus_rc_put_raw ( rc , quant , f - > fine_bits [ i ] ) ;
offset = 0.5f - ( ( quant + 0.5f ) * ( 1 < < ( 14 - f - > fine_bits [ i ] ) ) / 16384.0f ) ;
block - > error_energy [ i ] - = offset ;
}
}
}
static void celt_quant_final ( OpusEncContext * s , OpusRangeCoder * rc , CeltFrame * f )
{
int i , ch , priority ;
for ( priority = 0 ; priority < 2 ; priority + + ) {
for ( i = f - > start_band ; i < f - > end_band & & ( f - > framebits - opus_rc_tell ( rc ) ) > = f - > channels ; i + + ) {
if ( f - > fine_priority [ i ] ! = priority | | f - > fine_bits [ i ] > = CELT_MAX_FINE_BITS )
continue ;
for ( ch = 0 ; ch < f - > channels ; ch + + ) {
CeltBlock * block = & f - > block [ ch ] ;
const float err = block - > error_energy [ i ] ;
const float offset = 0.5f * ( 1 < < ( 14 - f - > fine_bits [ i ] - 1 ) ) / 16384.0f ;
const int sign = FFABS ( err + offset ) < FFABS ( err - offset ) ;
ff_opus_rc_put_raw ( rc , sign , 1 ) ;
block - > error_energy [ i ] - = offset * ( 1 - 2 * sign ) ;
}
}
}
}
static void celt_quant_bands ( OpusRangeCoder * rc , CeltFrame * f )
{
float lowband_scratch [ 8 * 22 ] ;
float norm [ 2 * 8 * 100 ] ;
int totalbits = ( f - > framebits < < 3 ) - f - > anticollapse_needed ;
int update_lowband = 1 ;
int lowband_offset = 0 ;
int i , j ;
for ( i = f - > start_band ; i < f - > end_band ; i + + ) {
uint32_t cm [ 2 ] = { ( 1 < < f - > blocks ) - 1 , ( 1 < < f - > blocks ) - 1 } ;
int band_offset = ff_celt_freq_bands [ i ] < < f - > size ;
int band_size = ff_celt_freq_range [ i ] < < f - > size ;
float * X = f - > block [ 0 ] . coeffs + band_offset ;
float * Y = ( f - > channels = = 2 ) ? f - > block [ 1 ] . coeffs + band_offset : NULL ;
int consumed = opus_rc_tell_frac ( rc ) ;
float * norm2 = norm + 8 * 100 ;
int effective_lowband = - 1 ;
int b = 0 ;
/* Compute how many bits we want to allocate to this band */
if ( i ! = f - > start_band )
f - > remaining - = consumed ;
f - > remaining2 = totalbits - consumed - 1 ;
if ( i < = f - > coded_bands - 1 ) {
int curr_balance = f - > remaining / FFMIN ( 3 , f - > coded_bands - i ) ;
b = av_clip_uintp2 ( FFMIN ( f - > remaining2 + 1 , f - > pulses [ i ] + curr_balance ) , 14 ) ;
}
if ( ff_celt_freq_bands [ i ] - ff_celt_freq_range [ i ] > = ff_celt_freq_bands [ f - > start_band ] & &
( update_lowband | | lowband_offset = = 0 ) )
lowband_offset = i ;
/* Get a conservative estimate of the collapse_mask's for the bands we're
going to be folding from . */
if ( lowband_offset ! = 0 & & ( f - > spread ! = CELT_SPREAD_AGGRESSIVE | |
f - > blocks > 1 | | f - > tf_change [ i ] < 0 ) ) {
int foldstart , foldend ;
/* This ensures we never repeat spectral content within one band */
effective_lowband = FFMAX ( ff_celt_freq_bands [ f - > start_band ] ,
ff_celt_freq_bands [ lowband_offset ] - ff_celt_freq_range [ i ] ) ;
foldstart = lowband_offset ;
while ( ff_celt_freq_bands [ - - foldstart ] > effective_lowband ) ;
foldend = lowband_offset - 1 ;
while ( ff_celt_freq_bands [ + + foldend ] < effective_lowband + ff_celt_freq_range [ i ] ) ;
cm [ 0 ] = cm [ 1 ] = 0 ;
for ( j = foldstart ; j < foldend ; j + + ) {
cm [ 0 ] | = f - > block [ 0 ] . collapse_masks [ j ] ;
cm [ 1 ] | = f - > block [ f - > channels - 1 ] . collapse_masks [ j ] ;
}
}
if ( f - > dual_stereo & & i = = f - > intensity_stereo ) {
/* Switch off dual stereo to do intensity */
f - > dual_stereo = 0 ;
for ( j = ff_celt_freq_bands [ f - > start_band ] < < f - > size ; j < band_offset ; j + + )
norm [ j ] = ( norm [ j ] + norm2 [ j ] ) / 2 ;
}
if ( f - > dual_stereo ) {
cm [ 0 ] = f - > pvq - > encode_band ( f - > pvq , f , rc , i , X , NULL , band_size , b / 2 , f - > blocks ,
effective_lowband ! = - 1 ? norm + ( effective_lowband < < f - > size ) : NULL , f - > size ,
norm + band_offset , 0 , 1.0f , lowband_scratch , cm [ 0 ] ) ;
cm [ 1 ] = f - > pvq - > encode_band ( f - > pvq , f , rc , i , Y , NULL , band_size , b / 2 , f - > blocks ,
effective_lowband ! = - 1 ? norm2 + ( effective_lowband < < f - > size ) : NULL , f - > size ,
norm2 + band_offset , 0 , 1.0f , lowband_scratch , cm [ 1 ] ) ;
} else {
cm [ 0 ] = f - > pvq - > encode_band ( f - > pvq , f , rc , i , X , Y , band_size , b , f - > blocks ,
effective_lowband ! = - 1 ? norm + ( effective_lowband < < f - > size ) : NULL , f - > size ,
norm + band_offset , 0 , 1.0f , lowband_scratch , cm [ 0 ] | cm [ 1 ] ) ;
cm [ 1 ] = cm [ 0 ] ;
}
f - > block [ 0 ] . collapse_masks [ i ] = ( uint8_t ) cm [ 0 ] ;
f - > block [ f - > channels - 1 ] . collapse_masks [ i ] = ( uint8_t ) cm [ 1 ] ;
f - > remaining + = f - > pulses [ i ] + consumed ;
/* Update the folding position only as long as we have 1 bit/sample depth */
update_lowband = ( b > band_size < < 3 ) ;
}
}
static void celt_encode_frame ( OpusEncContext * s , OpusRangeCoder * rc ,
CeltFrame * f , int index )
{
int i , ch ;
ff_opus_rc_enc_init ( rc ) ;
ff_opus_psy_celt_frame_init ( & s - > psyctx , f , index ) ;
celt_frame_setup_input ( s , f ) ;
if ( f - > silence ) {
if ( f - > framebits > = 16 )
ff_opus_rc_enc_log ( rc , 1 , 15 ) ; /* Silence (if using explicit singalling) */
for ( ch = 0 ; ch < s - > channels ; ch + + )
memset ( s - > last_quantized_energy [ ch ] , 0.0f , sizeof ( float ) * CELT_MAX_BANDS ) ;
return ;
}
/* Filters */
celt_apply_preemph_filter ( s , f ) ;
if ( f - > pfilter ) {
ff_opus_rc_enc_log ( rc , 0 , 15 ) ;
celt_enc_quant_pfilter ( rc , f ) ;
}
/* Transform */
celt_frame_mdct ( s , f ) ;
/* Need to handle transient/non-transient switches at any point during analysis */
while ( ff_opus_psy_celt_frame_process ( & s - > psyctx , f , index ) )
celt_frame_mdct ( s , f ) ;
ff_opus_rc_enc_init ( rc ) ;
/* Silence */
ff_opus_rc_enc_log ( rc , 0 , 15 ) ;
/* Pitch filter */
if ( ! f - > start_band & & opus_rc_tell ( rc ) + 16 < = f - > framebits )
celt_enc_quant_pfilter ( rc , f ) ;
/* Transient flag */
if ( f - > size & & opus_rc_tell ( rc ) + 3 < = f - > framebits )
ff_opus_rc_enc_log ( rc , f - > transient , 3 ) ;
/* Main encoding */
celt_quant_coarse ( rc , f , s - > last_quantized_energy ) ;
celt_enc_tf ( rc , f ) ;
ff_celt_enc_bitalloc ( rc , f ) ;
celt_quant_fine ( rc , f ) ;
celt_quant_bands ( rc , f ) ;
/* Anticollapse bit */
if ( f - > anticollapse_needed )
ff_opus_rc_put_raw ( rc , f - > anticollapse , 1 ) ;
/* Final per-band energy adjustments from leftover bits */
celt_quant_final ( s , rc , f ) ;
for ( ch = 0 ; ch < f - > channels ; ch + + ) {
CeltBlock * block = & f - > block [ ch ] ;
for ( i = 0 ; i < CELT_MAX_BANDS ; i + + )
s - > last_quantized_energy [ ch ] [ i ] = block - > energy [ i ] + block - > error_energy [ i ] ;
}
}
static inline int write_opuslacing ( uint8_t * dst , int v )
{
dst [ 0 ] = FFMIN ( v - FFALIGN ( v - 255 , 4 ) , v ) ;
dst [ 1 ] = v - dst [ 0 ] > > 2 ;
return 1 + ( v > = 252 ) ;
}
static void opus_packet_assembler ( OpusEncContext * s , AVPacket * avpkt )
{
int i , offset , fsize_needed ;
/* Write toc */
opus_gen_toc ( s , avpkt - > data , & offset , & fsize_needed ) ;
/* Frame sizes if needed */
if ( fsize_needed ) {
for ( i = 0 ; i < s - > packet . frames - 1 ; i + + ) {
offset + = write_opuslacing ( avpkt - > data + offset ,
s - > frame [ i ] . framebits > > 3 ) ;
}
}
/* Packets */
for ( i = 0 ; i < s - > packet . frames ; i + + ) {
ff_opus_rc_enc_end ( & s - > rc [ i ] , avpkt - > data + offset ,
s - > frame [ i ] . framebits > > 3 ) ;
offset + = s - > frame [ i ] . framebits > > 3 ;
}
avpkt - > size = offset ;
}
/* Used as overlap for the first frame and padding for the last encoded packet */
static AVFrame * spawn_empty_frame ( OpusEncContext * s )
{
int i ;
AVFrame * f = av_frame_alloc ( ) ;
if ( ! f )
return NULL ;
f - > format = s - > avctx - > sample_fmt ;
f - > nb_samples = s - > avctx - > frame_size ;
f - > channel_layout = s - > avctx - > channel_layout ;
if ( av_frame_get_buffer ( f , 4 ) ) {
av_frame_free ( & f ) ;
return NULL ;
}
for ( i = 0 ; i < s - > channels ; i + + ) {
size_t bps = av_get_bytes_per_sample ( f - > format ) ;
memset ( f - > extended_data [ i ] , 0 , bps * f - > nb_samples ) ;
}
return f ;
}
static int opus_encode_frame ( AVCodecContext * avctx , AVPacket * avpkt ,
const AVFrame * frame , int * got_packet_ptr )
{
OpusEncContext * s = avctx - > priv_data ;
int i , ret , frame_size , alloc_size = 0 ;
if ( frame ) { /* Add new frame to queue */
if ( ( ret = ff_af_queue_add ( & s - > afq , frame ) ) < 0 )
return ret ;
ff_bufqueue_add ( avctx , & s - > bufqueue , av_frame_clone ( frame ) ) ;
} else {
ff_opus_psy_signal_eof ( & s - > psyctx ) ;
if ( ! s - > afq . remaining_samples )
return 0 ; /* We've been flushed and there's nothing left to encode */
}
/* Run the psychoacoustic system */
if ( ff_opus_psy_process ( & s - > psyctx , & s - > packet ) )
return 0 ;
frame_size = OPUS_BLOCK_SIZE ( s - > packet . framesize ) ;
if ( ! frame ) {
/* This can go negative, that's not a problem, we only pad if positive */
int pad_empty = s - > packet . frames * ( frame_size / s - > avctx - > frame_size ) - s - > bufqueue . available + 1 ;
/* Pad with empty 2.5 ms frames to whatever framesize was decided,
* this should only happen at the very last flush frame . The frames
* allocated here will be freed ( because they have no other references )
* after they get used by celt_frame_setup_input ( ) */
for ( i = 0 ; i < pad_empty ; i + + ) {
AVFrame * empty = spawn_empty_frame ( s ) ;
if ( ! empty )
return AVERROR ( ENOMEM ) ;
ff_bufqueue_add ( avctx , & s - > bufqueue , empty ) ;
}
}
for ( i = 0 ; i < s - > packet . frames ; i + + ) {
celt_encode_frame ( s , & s - > rc [ i ] , & s - > frame [ i ] , i ) ;
alloc_size + = s - > frame [ i ] . framebits > > 3 ;
}
/* Worst case toc + the frame lengths if needed */
alloc_size + = 2 + s - > packet . frames * 2 ;
if ( ( ret = ff_alloc_packet2 ( avctx , avpkt , alloc_size , 0 ) ) < 0 )
return ret ;
/* Assemble packet */
opus_packet_assembler ( s , avpkt ) ;
/* Update the psychoacoustic system */
ff_opus_psy_postencode_update ( & s - > psyctx , s - > frame , s - > rc ) ;
/* Remove samples from queue and skip if needed */
ff_af_queue_remove ( & s - > afq , s - > packet . frames * frame_size , & avpkt - > pts , & avpkt - > duration ) ;
if ( s - > packet . frames * frame_size > avpkt - > duration ) {
uint8_t * side = av_packet_new_side_data ( avpkt , AV_PKT_DATA_SKIP_SAMPLES , 10 ) ;
if ( ! side )
return AVERROR ( ENOMEM ) ;
AV_WL32 ( & side [ 4 ] , s - > packet . frames * frame_size - avpkt - > duration + 120 ) ;
}
* got_packet_ptr = 1 ;
return 0 ;
}
static av_cold int opus_encode_end ( AVCodecContext * avctx )
{
int i ;
OpusEncContext * s = avctx - > priv_data ;
for ( i = 0 ; i < CELT_BLOCK_NB ; i + + )
ff_mdct15_uninit ( & s - > mdct [ i ] ) ;
ff_celt_pvq_uninit ( & s - > pvq ) ;
av_freep ( & s - > dsp ) ;
av_freep ( & s - > frame ) ;
av_freep ( & s - > rc ) ;
ff_af_queue_close ( & s - > afq ) ;
ff_opus_psy_end ( & s - > psyctx ) ;
ff_bufqueue_discard_all ( & s - > bufqueue ) ;
av_freep ( & avctx - > extradata ) ;
return 0 ;
}
static av_cold int opus_encode_init ( AVCodecContext * avctx )
{
int i , ch , ret , max_frames ;
OpusEncContext * s = avctx - > priv_data ;
s - > avctx = avctx ;
s - > channels = avctx - > channels ;
/* Opus allows us to change the framesize on each packet (and each packet may
* have multiple frames in it ) but we can ' t change the codec ' s frame size on
* runtime , so fix it to the lowest possible number of samples and use a queue
* to accumulate AVFrames until we have enough to encode whatever the encoder
* decides is the best */
avctx - > frame_size = 120 ;
/* Initial padding will change if SILK is ever supported */
avctx - > initial_padding = 120 ;
if ( ! avctx - > bit_rate ) {
int coupled = ff_opus_default_coupled_streams [ s - > channels - 1 ] ;
avctx - > bit_rate = coupled * ( 96000 ) + ( s - > channels - coupled * 2 ) * ( 48000 ) ;
} else if ( avctx - > bit_rate < 6000 | | avctx - > bit_rate > 255000 * s - > channels ) {
int64_t clipped_rate = av_clip ( avctx - > bit_rate , 6000 , 255000 * s - > channels ) ;
av_log ( avctx , AV_LOG_ERROR , " Unsupported bitrate % " PRId64 " kbps, clipping to % " PRId64 " kbps \n " ,
avctx - > bit_rate / 1000 , clipped_rate / 1000 ) ;
avctx - > bit_rate = clipped_rate ;
}
/* Extradata */
avctx - > extradata_size = 19 ;
avctx - > extradata = av_malloc ( avctx - > extradata_size + AV_INPUT_BUFFER_PADDING_SIZE ) ;
if ( ! avctx - > extradata )
return AVERROR ( ENOMEM ) ;
opus_write_extradata ( avctx ) ;
ff_af_queue_init ( avctx , & s - > afq ) ;
if ( ( ret = ff_celt_pvq_init ( & s - > pvq ) ) < 0 )
return ret ;
if ( ! ( s - > dsp = avpriv_float_dsp_alloc ( avctx - > flags & AV_CODEC_FLAG_BITEXACT ) ) )
return AVERROR ( ENOMEM ) ;
/* I have no idea why a base scaling factor of 68 works, could be the twiddles */
for ( i = 0 ; i < CELT_BLOCK_NB ; i + + )
if ( ( ret = ff_mdct15_init ( & s - > mdct [ i ] , 0 , i + 3 , 68 < < ( CELT_BLOCK_NB - 1 - i ) ) ) )
return AVERROR ( ENOMEM ) ;
/* Zero out previous energy (matters for inter first frame) */
for ( ch = 0 ; ch < s - > channels ; ch + + )
memset ( s - > last_quantized_energy [ ch ] , 0.0f , sizeof ( float ) * CELT_MAX_BANDS ) ;
/* Allocate an empty frame to use as overlap for the first frame of audio */
ff_bufqueue_add ( avctx , & s - > bufqueue , spawn_empty_frame ( s ) ) ;
if ( ! ff_bufqueue_peek ( & s - > bufqueue , 0 ) )
return AVERROR ( ENOMEM ) ;
if ( ( ret = ff_opus_psy_init ( & s - > psyctx , s - > avctx , & s - > bufqueue , & s - > options ) ) )
return ret ;
/* Frame structs and range coder buffers */
max_frames = ceilf ( FFMIN ( s - > options . max_delay_ms , 120.0f ) / 2.5f ) ;
s - > frame = av_malloc ( max_frames * sizeof ( CeltFrame ) ) ;
if ( ! s - > frame )
return AVERROR ( ENOMEM ) ;
s - > rc = av_malloc ( max_frames * sizeof ( OpusRangeCoder ) ) ;
if ( ! s - > rc )
return AVERROR ( ENOMEM ) ;
for ( i = 0 ; i < max_frames ; i + + ) {
s - > frame [ i ] . dsp = s - > dsp ;
s - > frame [ i ] . avctx = s - > avctx ;
s - > frame [ i ] . seed = 0 ;
s - > frame [ i ] . pvq = s - > pvq ;
s - > frame [ i ] . block [ 0 ] . emph_coeff = s - > frame [ i ] . block [ 1 ] . emph_coeff = 0.0f ;
}
return 0 ;
}
# define OPUSENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static const AVOption opusenc_options [ ] = {
{ " opus_delay " , " Maximum delay in milliseconds " , offsetof ( OpusEncContext , options . max_delay_ms ) , AV_OPT_TYPE_FLOAT , { . dbl = OPUS_MAX_LOOKAHEAD } , 2.5f , OPUS_MAX_LOOKAHEAD , OPUSENC_FLAGS , " max_delay_ms " } ,
{ NULL } ,
} ;
static const AVClass opusenc_class = {
. class_name = " Opus encoder " ,
. item_name = av_default_item_name ,
. option = opusenc_options ,
. version = LIBAVUTIL_VERSION_INT ,
} ;
static const AVCodecDefault opusenc_defaults [ ] = {
{ " b " , " 0 " } ,
{ " compression_level " , " 10 " } ,
{ NULL } ,
} ;
AVCodec ff_opus_encoder = {
. name = " opus " ,
. long_name = NULL_IF_CONFIG_SMALL ( " Opus " ) ,
. type = AVMEDIA_TYPE_AUDIO ,
. id = AV_CODEC_ID_OPUS ,
. defaults = opusenc_defaults ,
. priv_class = & opusenc_class ,
. priv_data_size = sizeof ( OpusEncContext ) ,
. init = opus_encode_init ,
. encode2 = opus_encode_frame ,
. close = opus_encode_end ,
. caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP ,
. capabilities = AV_CODEC_CAP_EXPERIMENTAL | AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY ,
. supported_samplerates = ( const int [ ] ) { 48000 , 0 } ,
. channel_layouts = ( const uint64_t [ ] ) { AV_CH_LAYOUT_MONO ,
AV_CH_LAYOUT_STEREO , 0 } ,
. sample_fmts = ( const enum AVSampleFormat [ ] ) { AV_SAMPLE_FMT_FLTP ,
AV_SAMPLE_FMT_NONE } ,
} ;