diff --git a/apps/decoder.c b/apps/decoder.c index 354d611a95b7cec68bed7428394b06d182b04694..85f625fe1387d7f4607d1ac36371052a5aa23789 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -802,6 +802,7 @@ int main( } } + /*------------------------------------------------------------------------------------------* * Allocate output data buffer *------------------------------------------------------------------------------------------*/ @@ -2089,7 +2090,12 @@ static ivas_error decodeG192( IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; uint16_t nSamplesAvailableNext; bool needNewFrame; +#ifdef MEM_ALLOC_APP_DEC + uint16_t nSamplesRendered; + int16_t nSamplesRendered_loop, nSamplesToRender; +#else int16_t nSamplesRendered, nSamplesRendered_loop, nSamplesToRender; +#endif #ifdef DEBUGGING #ifdef VARIABLE_SPEED_DECODING TsmScaleFileReader *tsmScaleFileReader = NULL; @@ -2420,7 +2426,40 @@ static ivas_error decodeG192( fprintf( stderr, "\nError: could not feed frame to decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } + +#ifdef MEM_ALLOC_APP_DEC + /* Setup ISAR handle */ + if ( isSplitRend ) + { + if ( ( error = IVAS_DEC_split_rend_setup( hIvasDec, splitRendBits ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_split_rend_setup failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + /* Reconfigure IVAS decoder handles and reallocate the memory if IVAS total bitrate has changed */ + if ( ( error = IVAS_DEC_Setup( hIvasDec, NULL, IVAS_DEC_PCM_INT16, pcmBuf + nSamplesRendered * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_Setup failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } +#endif } +#ifdef MEM_ALLOC_APP_DEC + else + { + /* Setup ISAR handle */ + if ( isSplitRend ) + { + if ( ( error = IVAS_DEC_split_rend_setup( hIvasDec, splitRendBits ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_split_rend_setup failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + } +#endif if ( isSplitRend ) { @@ -2435,7 +2474,11 @@ static ivas_error decodeG192( } else { +#ifdef MEM_ALLOC_APP_DEC + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, IVAS_DEC_PCM_INT16, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame, 1 ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, IVAS_DEC_PCM_INT16, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError in IVAS_DEC_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -3245,18 +3288,46 @@ static ivas_error decodeVoIP( break; } - /* decode and get samples */ #ifdef SUPPORT_JBM_TRACEFILE +#ifdef MEM_ALLOC_APP_DEC + int16_t nSamplesRendered_pre = 0; + + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, &nSamplesRendered_pre, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK ) +#endif +#else +#ifdef MEM_ALLOC_APP_DEC + int16_t nSamplesRendered_pre = 0; + + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, &nSamplesRendered_pre ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK ) +#endif #endif { fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } +#ifdef MEM_ALLOC_APP_DEC + /* Reconfigure IVAS decoder handles and reallocate the memory if IVAS total bitrate has changed */ + uint16_t nSamplesRendered2 = 0; + if ( ( error = IVAS_DEC_Setup( hIvasDec, &nSamplesRendered2, IVAS_DEC_PCM_INT16, pcmBuf + nSamplesRendered_pre * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_Setup failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + return error; + } + + /* decode frame and get samples */ + if ( ( error = IVAS_DEC_GetSamples_wrapper( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, pcmBuf, nSamplesRendered_pre ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetSamples_wrapper: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } +#endif + /* write JBM Offset file entry */ if ( jbmOffsetWriter != NULL ) { diff --git a/apps/encoder.c b/apps/encoder.c index b00f4f75fdc85f3dc72e6ad1a0a9568e70e2a60d..914795202012375e150d70e06e97c16c84c71170 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -368,9 +368,15 @@ int main( goto cleanup; } +#ifdef MEM_ALLOC_APP + /*------------------------------------------------------------------------------------------* + * Configure the encoder + *------------------------------------------------------------------------------------------*/ +#else /*------------------------------------------------------------------------------------------* * Configure and initialize (allocate memory for static variables) the encoder *------------------------------------------------------------------------------------------*/ +#endif switch ( arg.inputFormat ) { @@ -449,6 +455,18 @@ int main( goto cleanup; } +#ifdef MEM_ALLOC_APP + /*------------------------------------------------------------------------------------------* + * Initialize (allocate memory for static variables) the encoder + *------------------------------------------------------------------------------------------*/ + + if ( ( error = IVAS_ENC_Initialize( hIvasEnc ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_ENC_Initialize failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) ); + goto cleanup; + } +#endif + if ( ( error = IVAS_ENC_PrintConfig( hIvasEnc, caConfig.channelAwareModeEnabled ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\n IVAS_ENC_PrintConfig failed %s\n\n", IVAS_ENC_GetErrorMessage( error ) ); @@ -756,6 +774,14 @@ int main( } } +#ifdef MEM_ALLOC_APP + /* Reconfigure IVAS encoder handles and reallocate the memory if IVAS total bitrate has changed */ + if ( ( error = IVAS_ENC_Reconfigure( hIvasEnc ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + /* *** Encode one frame *** */ if ( ( error = IVAS_ENC_EncodeFrameToSerial( hIvasEnc, pcmBuf, pcmBufSize, bitStream, &numBits ) ) != IVAS_ERR_OK ) { diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index b534415e15956aeb24cdd2c8bc938cd729a48478..5179e0ba0c09316581b171c29bf69ed9a98db0ed 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -279,6 +279,12 @@ void ivas_destroy_enc( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ); +#ifdef MEM_ALLOC_APP +ivas_error ivas_reconfig_enc( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); +#endif + ivas_error ivas_initialize_MD_bstr_enc( BSTR_ENC_HANDLE *hBstr, /* o : encoder MD bitstream handle */ Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ @@ -4929,10 +4935,20 @@ void ivas_masa_estimate_energy( const int16_t nchan_transport /* i : number of MASA input/transport channels */ ); +#ifdef MEM_ALLOC_APP +ivas_error ivas_masa_enc_config_memory( +#else ivas_error ivas_masa_enc_config( +#endif Encoder_Struct* st_ivas /* i/o: IVAS encoder structure */ ); +#ifdef MEM_ALLOC_APP +void ivas_masa_enc_init( + Encoder_Struct* st_ivas /* i/o: IVAS encoder structure */ +); +#endif + void ivas_masa_set_elements( const int32_t ivas_total_brate, /* i : codec total bitrate */ const int16_t mc_mode, /* i : MC format mode */ diff --git a/lib_com/options.h b/lib_com/options.h index 02e3196e52d0c359de038b315a8ac36681f206ca..0e506b36d2259c4037702e3bf3ab4d83abe935ff 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -163,6 +163,11 @@ #define FIX_1099_JBM_MD_HANDLE_ALLOC /* VA: issue 1099: Limit the allocation of `hJbmMetadata` handle to MASA and OMASA only */ + +#define MEM_ALLOC_APP /* VA: call memory allocate/reallocation from the application */ +#define MEM_ALLOC_APP_DEC /* VA: call memory allocate/reallocation from the application, decoder part */ + + /* #################### End BE switches ################################## */ /* #################### Start NON-BE switches ############################ */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 66032833c158178a9f960c247886674ea9ebdd06..7f0b2bf0b0ec99f0683e59a3606045ef205c66c2 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -90,6 +90,9 @@ struct IVAS_DEC bool updateOrientation; uint16_t nSamplesAvailableNext; int16_t nSamplesRendered; +#ifdef MEM_ALLOC_APP_DEC + int16_t nSamplesRendered_flush; +#endif int16_t nTransportChannelsOld; int16_t amrwb_rfc4867_flag; /* MIME from rfc4867 is used */ int16_t sdp_hf_only; /* RTP payload format parameter: only Header-Full format without zero padding for size collision avoidance */ @@ -110,7 +113,9 @@ static ivas_error evs_dec_main( Decoder_Struct *st_ivas, const int16_t nOutSampl static ivas_error input_format_API_to_internal( IVAS_DEC_INPUT_FORMAT input_format, int16_t *bitstream_format_internal, int16_t *sdp_hf_only, const bool is_voip_enabled ); static void init_decoder_config( DECODER_CONFIG_HANDLE hDecoderConfig ); static ivas_error IVAS_DEC_VoIP_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ); +#ifndef MEM_ALLOC_APP_DEC static ivas_error IVAS_DEC_Setup( IVAS_DEC_HANDLE hIvasDec, uint16_t *nTcBufferGranularity, uint8_t *nTransportChannels, uint8_t *nOutChannels, uint16_t *nSamplesRendered, const IVAS_DEC_PCM_TYPE pcmType, void *data ); +#endif static ivas_error IVAS_DEC_GetTcSamples( IVAS_DEC_HANDLE hIvasDec, float *pcmBuf, int16_t *nOutSamples ); static ivas_error IVAS_DEC_RendererFeedTcSamples( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesForRendering, int16_t *nSamplesResidual, float *pcmBuf ); static ivas_error IVAS_DEC_GetRenderedSamples( IVAS_DEC_HANDLE hIvasDec, const uint16_t nSamplesForRendering, uint16_t *nSamplesRendered, uint16_t *nSamplesAvailableNext, const IVAS_DEC_PCM_TYPE pcmType, void *pcmBuf ); @@ -166,6 +171,9 @@ ivas_error IVAS_DEC_Open( hIvasDec->nTransportChannelsOld = 0; hIvasDec->nSamplesAvailableNext = 0; hIvasDec->nSamplesRendered = 0; +#ifdef MEM_ALLOC_APP_DEC + hIvasDec->nSamplesRendered_flush = 0; +#endif hIvasDec->nSamplesFrame = 0; hIvasDec->hasBeenFedFrame = false; hIvasDec->hasBeenFedFirstGoodFrame = false; @@ -517,6 +525,9 @@ ivas_error IVAS_DEC_Configure( hIvasDec->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); hIvasDec->nSamplesAvailableNext = 0; hIvasDec->nSamplesRendered = 0; +#ifdef MEM_ALLOC_APP_DEC + hIvasDec->nSamplesRendered_flush = 0; +#endif hIvasDec->tsm_scale = 100; hIvasDec->tsm_max_scaling = 0; hIvasDec->tsm_quality = 1.0f; @@ -865,6 +876,9 @@ ivas_error IVAS_DEC_FeedFrame_Serial( hIvasDec->needNewFrame = false; hIvasDec->hasBeenFedFrame = true; hIvasDec->nSamplesRendered = 0; +#ifdef MEM_ALLOC_APP_DEC + hIvasDec->nSamplesRendered_flush = 0; +#endif hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; return IVAS_ERR_OK; @@ -877,17 +891,24 @@ ivas_error IVAS_DEC_FeedFrame_Serial( * Main function to decode to PCM data *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ void *pcmBuf, /* o : output synthesis signal */ int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ - bool *needNewFrame /* o : indication that the decoder needs a new frame */ +#ifdef MEM_ALLOC_APP_DEC + bool *needNewFrame, /* o : indication that the decoder needs a new frame */ + const int16_t flag_decode /* i : flag to indicate decoding */ +#else + bool *needNewFrame /* o : indication that the decoder needs a new frame */ +#endif ) { ivas_error error; +#ifdef MEM_ALLOC_APP_DEC + Decoder_Struct *st_ivas; +#endif int16_t nOutSamplesElse, nSamplesToRender; uint16_t nSamplesRendered, nSamplesRendered_loop, l_ts, nTimeScalerOutSamples; uint8_t nTransportChannels, nOutChannels; @@ -903,6 +924,10 @@ ivas_error IVAS_DEC_GetSamples( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef MEM_ALLOC_APP_DEC + st_ivas = hIvasDec->st_ivas; + +#endif if ( hIvasDec->updateOrientation ) { /*----------------------------------------------------------------* @@ -954,18 +979,50 @@ ivas_error IVAS_DEC_GetSamples( /* check if we need to run the setup function */ if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) { +#ifdef MEM_ALLOC_APP_DEC + if ( flag_decode == 0 ) + { + /* do not run decoder */ + *nOutSamples = -1; + + return IVAS_ERR_OK; + } + + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) + { + nTransportChannels = MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; + nOutChannels = MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; + } + else + { + nTransportChannels = 1; + nOutChannels = 1; + } + } + else + { + l_ts = st_ivas->hTcBuffer->n_samples_granularity; + nTransportChannels = (uint8_t) st_ivas->hTcBuffer->nchan_transport_jbm; + nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; + nSamplesRendered_loop = hIvasDec->nSamplesRendered; + nSamplesRendered = hIvasDec->nSamplesRendered_flush; + } +#else /* setup */ if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &nSamplesRendered_loop, pcmType, pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ) ) ) != IVAS_ERR_OK ) - { return error; } +#endif } { /* check if we need to run the setup function, tc decoding and feeding the renderer */ if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) { int16_t nResidualSamples, nSamplesTcsScaled; + nSamplesRendered += nSamplesRendered_loop; if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm && nTransportChannels != hIvasDec->nTransportChannelsOld ) @@ -1052,6 +1109,35 @@ ivas_error IVAS_DEC_GetSamples( } +#ifdef MEM_ALLOC_APP_DEC +/*---------------------------------------------------------------------* + * IVAS_DEC_split_rend_setup( ) + * + * + *---------------------------------------------------------------------*/ +// VE: todo - this could be moved to isar_lib +ivas_error IVAS_DEC_split_rend_setup( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +) +{ + Decoder_Struct *st_ivas; + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + ivas_error error; + + st_ivas = hIvasDec->st_ivas; + hSplitBinRend = st_ivas->hSplitBinRend; + + if ( ( error = isar_set_split_rend_setup( hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) + { + return error; + } + + return error; +} + +#endif + /*---------------------------------------------------------------------* * IVAS_DEC_GetSplitBinauralBitstream( ) * @@ -1094,12 +1180,14 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( *needNewFrame = false; hSplitBinRend = st_ivas->hSplitBinRend; +#ifndef MEM_ALLOC_APP_DEC if ( ( error = isar_set_split_rend_setup( hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) { return error; } +#endif numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; if ( st_ivas->hDecoderConfig->render_framesize != IVAS_RENDER_FRAMESIZE_20MS && @@ -1133,7 +1221,11 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( } /* Decode and render */ +#ifdef MEM_ALLOC_APP_DEC + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, numSamplesPerChannelToDecode, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame, 1 ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_GetSamples( hIvasDec, numSamplesPerChannelToDecode, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1248,22 +1340,55 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( * *---------------------------------------------------------------------*/ -static ivas_error IVAS_DEC_Setup( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t *nTcBufferGranularity, /* o : granularity of the TC Buffer */ - uint8_t *nTransportChannels, /* o : number of decoded transport PCM channels */ - uint8_t *nOutChannels, /* o : number of decoded out channels (PCM or CLDFB) */ - uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame */ - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *data /* o : output synthesis signal */ -) +#ifndef MEM_ALLOC_APP_DEC +static +#endif + ivas_error + IVAS_DEC_Setup( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifndef MEM_ALLOC_APP_DEC + uint16_t *nTcBufferGranularity, /* o : granularity of the TC Buffer */ + uint8_t *nTransportChannels, /* o : number of decoded transport PCM channels */ + uint8_t *nOutChannels, /* o : number of decoded out channels (PCM or CLDFB) */ +#endif + uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ + ) { ivas_error error; +#ifndef MEM_ALLOC_APP_DEC *nSamplesRendered = 0; +#else + uint16_t nSamplesRendered_loc; + + nSamplesRendered_loc = 0; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || data == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) + { + /* no frame was fed, do nothing */ + return IVAS_ERR_OK; + } + + if ( !( hIvasDec->hasBeenFedFirstGoodFrame && ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) ) ) + { + /* no frame was fed, do nothing */ + return IVAS_ERR_OK; + } +#endif if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { +#ifdef MEM_ALLOC_APP_DEC + /* EVS decoding, do nothing */ + return IVAS_ERR_OK; +#else if ( hIvasDec->st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) { *nTransportChannels = MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; @@ -1274,6 +1399,7 @@ static ivas_error IVAS_DEC_Setup( *nTransportChannels = 1; *nOutChannels = 1; } +#endif } else { @@ -1291,22 +1417,27 @@ static ivas_error IVAS_DEC_Setup( if ( st_ivas->bfi == 0 ) { +#ifdef MEM_ALLOC_APP_DEC + if ( ( error = ivas_dec_setup( st_ivas, &nSamplesRendered_loc, pcm_type_API_to_internal( pcmType ), data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_dec_setup( st_ivas, nSamplesRendered, pcm_type_API_to_internal( pcmType ), data ) ) != IVAS_ERR_OK ) +#endif { return error; } } +#ifndef MEM_ALLOC_APP_DEC *nTransportChannels = (uint8_t) st_ivas->hTcBuffer->nchan_transport_jbm; *nTcBufferGranularity = (uint16_t) st_ivas->hTcBuffer->n_samples_granularity; *nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; - - +#endif /*-----------------------------------------------------------------* * ISAR: * - initialize ISAR handle at the first frame * - reconfigure the ISAR handle in case of bitrate switching (renderer might change) *-----------------------------------------------------------------*/ + if ( st_ivas->ini_frame == 0 && ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) ) ) { if ( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK ) @@ -1322,12 +1453,21 @@ static ivas_error IVAS_DEC_Setup( return error; } } + +#ifdef MEM_ALLOC_APP_DEC + /* Final updates */ + if ( nSamplesRendered != NULL ) + { + *nSamplesRendered = nSamplesRendered_loc; + } + + hIvasDec->nSamplesRendered_flush = nSamplesRendered_loc; +#endif } return IVAS_ERR_OK; } - /*---------------------------------------------------------------------* * IVAS_DEC_GetTcSamples( ) * @@ -2542,11 +2682,16 @@ ivas_error IVAS_DEC_TSM_SetQuality( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_VoIP_GetSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ +#ifdef MEM_ALLOC_APP_DEC + const uint32_t systemTimestamp_ms, /* i : current system timestamp */ + int16_t *nSamplesRendered_pre /* o : number of already rendered samples */ +#else const uint32_t systemTimestamp_ms /* i : current system timestamp */ +#endif #ifdef SUPPORT_JBM_TRACEFILE , JbmTraceFileWriterFn jbmWriterFn, @@ -2711,11 +2856,25 @@ ivas_error IVAS_DEC_VoIP_GetSamples( nSamplesToRender = nSamplesPerChannel - nSamplesRendered; /* render IVAS frames directly to the output buffer */ +#ifdef MEM_ALLOC_APP_DEC + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp, 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) +#endif { return error; } +#ifdef MEM_ALLOC_APP_DEC + if ( nSamplesRendered_loop == -1 ) + { + /* stop the rendering for now */ + *nSamplesRendered_pre = nSamplesRendered; + + break; + } +#endif + nSamplesRendered += nSamplesRendered_loop; update_voip_rendered20ms( hIvasDec, nSamplesRendered_loop ); } @@ -2724,6 +2883,47 @@ ivas_error IVAS_DEC_VoIP_GetSamples( return IVAS_ERR_OK; } +#ifdef MEM_ALLOC_APP_DEC + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSamples_wrapper( ) + * + * Main function to decode one frame in VoIP + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetSamples_wrapper( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + const int16_t nSamplesRendered_pre /* i : number of samples already rendered */ +) +{ + ivas_error error; + int16_t nOutChannels; + int16_t nSamplesToRender, nSamplesRendered_loop; + bool tmp; + + nOutChannels = hIvasDec->st_ivas->hDecoderConfig->nchan_out; + nSamplesToRender = nSamplesAsked - nSamplesRendered_pre; + + if ( hIvasDec->hasBeenFedFirstGoodFrame && hIvasDec->hasBeenFedFrame ) + { + /* render IVAS frames directly to the output buffer */ + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered_pre * nOutChannels ), &nSamplesRendered_loop, &tmp, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + + // nSamplesRendered_pre += nSamplesRendered_loop; + update_voip_rendered20ms( hIvasDec, nSamplesRendered_loop ); + } + + return IVAS_ERR_OK; +} + +#endif + /*---------------------------------------------------------------------* * update_voip_rendered20ms( ) * diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 0be389a61d764eecd2559adcc3ed1864f9e4b973..6571feb318094262c4105eaf650852093abebee6 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -141,6 +141,15 @@ void IVAS_DEC_Close( IVAS_DEC_HANDLE *phIvasDec /* i/o: pointer to IVAS decoder handle */ ); +#ifdef MEM_ALLOC_APP_DEC +/*! r: error code */ +ivas_error IVAS_DEC_Setup( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +); +#endif /* Decoding functions - should be called with a configured decoder handle */ @@ -159,9 +168,21 @@ ivas_error IVAS_DEC_GetSamples( const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ void *pcmBuf, /* o : output synthesis signal */ int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ +#ifdef MEM_ALLOC_APP_DEC + bool *needNewFrame, /* o : indication that the decoder needs a new frame */ + const int16_t flag_decode /* i : flag to indicate decoding */ +#else bool *needNewFrame /* o : indication that the decoder needs a new frame */ +#endif +); + +#ifdef MEM_ALLOC_APP_DEC +ivas_error IVAS_DEC_split_rend_setup( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ ); +#endif ivas_error IVAS_DEC_GetSplitBinauralBitstream( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ @@ -277,13 +298,28 @@ ivas_error IVAS_DEC_VoIP_GetSamples( uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ void *pcmBuf, /* o : output synthesis signal */ +#ifdef MEM_ALLOC_APP_DEC + const uint32_t systemTimestamp_ms, /* i : current system timestamp */ + int16_t *nSamplesRendered_pre /* o : number of already rendered samples */ +#else const uint32_t systemTimestamp_ms /* i : current system timestamp */ +#endif #ifdef SUPPORT_JBM_TRACEFILE , JbmTraceFileWriterFn jbmWriterFn, void* jbmWriter #endif ); +#ifdef MEM_ALLOC_APP_DEC +ivas_error IVAS_DEC_GetSamples_wrapper( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + const int16_t nSamplesRendered_pre /* i : number of samples already rendered */ +); + +#endif ivas_error IVAS_DEC_Flush( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c index 5ddcf9a506727f7d37ba32b00a4c56c0dd393e91..51e67e0cbff9a1d28a30a5b9a76800bc16311fc5 100644 --- a/lib_enc/ivas_enc.c +++ b/lib_enc/ivas_enc.c @@ -125,6 +125,7 @@ ivas_error ivas_enc( #ifdef DEBUG_MODE_LFE dbgwrite( data_f[LFE_CHANNEL], sizeof( float ), n_samples_chan, 1, "./res/lfe_input" ); #endif +#ifndef MEM_ALLOC_APP if ( ivas_format == SBA_FORMAT ) { @@ -141,6 +142,7 @@ ivas_error ivas_enc( } } +#endif /*----------------------------------------------------------------* * HP filtering *----------------------------------------------------------------*/ @@ -182,12 +184,13 @@ ivas_error ivas_enc( } else if ( ivas_format == ISM_FORMAT ) { +#ifndef MEM_ALLOC_APP /* select ISM format mode; reconfigure the ISM format encoder */ if ( ( error = ivas_ism_enc_config( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - +#endif if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { ivas_param_ism_enc( st_ivas, data_f, input_frame ); @@ -225,10 +228,14 @@ ivas_error ivas_enc( { ivas_masa_estimate_energy( st_ivas->hMasa, data_f, input_frame, st_ivas->nchan_transport ); /* energy-estimation uses TF-resolution: 4x24 */ +#ifdef MEM_ALLOC_APP + ivas_masa_enc_init( st_ivas ); +#else if ( ( error = ivas_masa_enc_config( st_ivas ) ) != IVAS_ERR_OK ) { return error; } +#endif if ( ( error = ivas_masa_encode( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, &nb_bits_metadata[0], st_ivas->nchan_transport, ivas_format, ivas_total_brate, hEncoderConfig->Opt_DTX_ON, st_ivas->nchan_transport == 2 ? st_ivas->hCPE[0]->element_mode : -1, ISM_MODE_NONE, -1, NULL, -1, NULL, 0, 0 ) ) != IVAS_ERR_OK ) @@ -290,10 +297,14 @@ ivas_error ivas_enc( /* Estimate TF-tile energy for the input MASA stream */ ivas_masa_estimate_energy( st_ivas->hMasa, &( data_f[hEncoderConfig->nchan_ism] ), input_frame, st_ivas->nchan_transport ); +#ifdef MEM_ALLOC_APP + ivas_masa_enc_init( st_ivas ); +#else if ( ( error = ivas_omasa_enc_config( st_ivas ) ) != IVAS_ERR_OK ) { return error; } +#endif set_s( nb_bits_metadata, 0, MAX_SCE + 1 ); idx_separated_object = 0; @@ -438,11 +449,23 @@ ivas_error ivas_enc( } else if ( ivas_format == MC_FORMAT ) { +#ifdef MEM_ALLOC_APP + /* write MC LS setup */ + if ( st_ivas->nSCE > 0 ) + { + push_indice( st_ivas->hSCE[0]->hCoreCoder[0]->hBstr, IND_SMODE, st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_BITS ); + } + else + { + push_indice( st_ivas->hCPE[0]->hCoreCoder[0]->hBstr, IND_SMODE, st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_BITS ); + } +#else /* select MC format mode; write MC LS setup; reconfigure the MC format encoder */ if ( ( error = ivas_mc_enc_config( st_ivas ) ) != IVAS_ERR_OK ) { return error; } +#endif hMetaData = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData : st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData; diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index a24007b21ae36cd4248dca34ba8f6705c3a6afbf..6f2c34e5f793799ab19af2bf351b604ba9c3a502 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -1213,6 +1213,69 @@ void ivas_destroy_enc( return; } + +#ifdef MEM_ALLOC_APP +/*------------------------------------------------------------------------- + * ivas_reconfig_enc() + * + * Reconfigure IVAS encoder handles and reallocate the memory based on + * changes of 'hEncoderConfig' parameters, typically ivas_total_brate + *-------------------------------------------------------------------------*/ + +ivas_error ivas_reconfig_enc( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +) +{ + ivas_error error; + IVAS_FORMAT ivas_format; + + ivas_format = st_ivas->hEncoderConfig->ivas_format; + + if ( ivas_format == STEREO_FORMAT ) + { + /* stereo_memory_enc() is called from ivas_cpe_enc() */ + return IVAS_ERR_OK; + } + else if ( ivas_format == ISM_FORMAT ) + { + /* select ISM format mode; reconfigure the ISM format encoder */ + error = ivas_ism_enc_config( st_ivas ); + } + else if ( ivas_format == SBA_FORMAT ) + { + /* reconfigure the SBA format encoder */ + error = ivas_sba_enc_reconfigure( st_ivas ); + } + else if ( ivas_format == MASA_FORMAT ) + { + /* reconfigure the MASA format encoder */ + error = ivas_masa_enc_config_memory( st_ivas ); + } + else if ( ivas_format == SBA_ISM_FORMAT ) + { + /* select ISM format mode; reconfigure the OSBA format encoder */ + error = ivas_osba_enc_reconfig( st_ivas ); + } + else if ( ivas_format == MASA_ISM_FORMAT ) + { + /* select ISM format mode; reconfigure the OMASA format encoder */ + error = ivas_omasa_enc_config( st_ivas ); + } + else if ( ivas_format == MC_FORMAT ) + { + /* select MC format mode; reconfigure the MC format encoder */ + error = ivas_mc_enc_config( st_ivas ); + } + else + { + return IVAS_ERROR( IVAS_ERR_INVALID_INPUT_FORMAT, "Error: unsupported input audio format" ); + } + + return error; +} +#endif + + /*------------------------------------------------------------------------- * ivas_initialize_MD_bstr_enc() * diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index 54691e864e63e6cc5b2af98591b2616953961814..457b28292f6f72eef93239e31154640abd128594 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -681,17 +681,31 @@ void ivas_masa_estimate_energy( } +#ifdef MEM_ALLOC_APP +/*-----------------------------------------------------------------------* + * ivas_masa_enc_config_memory() + * + * Frame-by-frame configuration of MASA encoder memory + *-----------------------------------------------------------------------*/ +#else /*-----------------------------------------------------------------------* * ivas_masa_enc_config() * * Frame-by-frame configuration of MASA encoder *-----------------------------------------------------------------------*/ +#endif +#ifdef MEM_ALLOC_APP +ivas_error ivas_masa_enc_config_memory( +#else ivas_error ivas_masa_enc_config( +#endif Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) { +#ifndef MEM_ALLOC_APP int16_t i; +#endif MASA_ENCODER_HANDLE hMasa; IVAS_QMETADATA_HANDLE hQMetaData; IVAS_FORMAT ivas_format; @@ -699,19 +713,23 @@ ivas_error ivas_masa_enc_config( uint8_t coherencePresent; uint8_t isActualTwoDir; /* Flag to tell that when there are two directions present in metadata, they both contain meaningful information. */ int32_t ivas_total_brate; +#ifndef MEM_ALLOC_APP uint8_t maxBand; int16_t maxBin, sf; +#endif ivas_error error; +#ifndef MEM_ALLOC_APP int32_t ism_total_brate; int32_t masa_total_brate; +#endif error = IVAS_ERR_OK; - hMasa = st_ivas->hMasa; hQMetaData = st_ivas->hQMetaData; ivas_format = st_ivas->hEncoderConfig->ivas_format; ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; +#ifndef MEM_ALLOC_APP ism_total_brate = 0; if ( ivas_format == MASA_ISM_FORMAT && st_ivas->nSCE > 0 && ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) ) { @@ -722,7 +740,7 @@ ivas_error ivas_masa_enc_config( } ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, hQMetaData, &st_ivas->hEncoderConfig->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE, ivas_format, st_ivas->ism_mode, ism_total_brate ); - +#endif hQMetaData->is_masa_ivas_format = 1; if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) @@ -759,6 +777,7 @@ ivas_error ivas_masa_enc_config( ivas_masa_set_coding_config( &( hMasa->config ), hMasa->data.band_mapping, ivas_total_brate, st_ivas->nchan_transport, ( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ); } +#ifndef MEM_ALLOC_APP /* Setup importance weights for two-direction band selection. */ if ( hMasa->config.numberOfDirections == 2 ) { @@ -806,6 +825,7 @@ ivas_error ivas_masa_enc_config( { set_c( (int8_t *) hMasa->data.twoDirBands, 0, hMasa->config.numCodingBands ); } +#endif /* Set qmeta to correct values */ if ( ( error = ivas_qmetadata_allocate_memory( hQMetaData, hMasa->config.numCodingBands, hMasa->config.numberOfDirections == 2 && hMasa->config.numTwoDirBands != 0 ? 2 : 1, hMasa->config.useCoherence ) ) != IVAS_ERR_OK ) @@ -813,6 +833,7 @@ ivas_error ivas_masa_enc_config( return error; } +#ifndef MEM_ALLOC_APP for ( i = 0; i < hQMetaData->no_directions; i++ ) { hQMetaData->q_direction[i].cfg.nbands = hMasa->config.numCodingBands; @@ -903,10 +924,192 @@ ivas_error ivas_masa_enc_config( st_ivas->hMasa->data.hOmasaData->lp_noise_CPE = ( st_ivas->hCPE[0]->hCoreCoder[0]->lp_noise + st_ivas->hCPE[0]->hCoreCoder[1]->lp_noise ) / CPE_CHANNELS; } } - +#endif return error; } +#ifdef MEM_ALLOC_APP + +/*-----------------------------------------------------------------------* + * ivas_masa_enc_init() + * + * Frame-by-frame configuration of MASA encoder + *-----------------------------------------------------------------------*/ + +void ivas_masa_enc_init( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +) +{ + int16_t i; + MASA_ENCODER_HANDLE hMasa; + IVAS_QMETADATA_HANDLE hQMetaData; + IVAS_FORMAT ivas_format; + int32_t ivas_total_brate; + uint8_t maxBand; + int16_t maxBin, sf; + int32_t ism_total_brate; + int32_t masa_total_brate; + + hMasa = st_ivas->hMasa; + hQMetaData = st_ivas->hQMetaData; + ivas_format = st_ivas->hEncoderConfig->ivas_format; + ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; + + ism_total_brate = 0; + if ( ivas_format == MASA_ISM_FORMAT && st_ivas->nSCE > 0 && ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) ) + { + for ( i = 0; i < st_ivas->nSCE; i++ ) + { + ism_total_brate += st_ivas->hSCE[i]->element_brate; + } + } + + ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, hQMetaData, &st_ivas->hEncoderConfig->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE, ivas_format, st_ivas->ism_mode, ism_total_brate ); + + /* Setup importance weights for two-direction band selection. */ + if ( hMasa->config.numberOfDirections == 2 ) + { + set_f( hMasa->data.importanceWeight, 1.0f, hMasa->config.numCodingBands ); + + if ( hMasa->config.numCodingBands == 5 ) + { + hMasa->data.importanceWeight[4] = 0.7f; + } + else if ( hMasa->config.numCodingBands == 8 ) + { + hMasa->data.importanceWeight[7] = 0.7f; + } + else if ( hMasa->config.numCodingBands == 10 ) + { + hMasa->data.importanceWeight[8] = 0.7f; + hMasa->data.importanceWeight[9] = 0.1f; + } + else if ( hMasa->config.numCodingBands == 12 ) + { + hMasa->data.importanceWeight[10] = 0.7f; + hMasa->data.importanceWeight[11] = 0.1f; + } + else if ( hMasa->config.numCodingBands == 18 ) + { + hMasa->data.importanceWeight[14] = 0.8f; + hMasa->data.importanceWeight[15] = 0.5f; + hMasa->data.importanceWeight[16] = 0.2f; + hMasa->data.importanceWeight[17] = 0.0f; + } + else if ( hMasa->config.numCodingBands == 24 ) + { + hMasa->data.importanceWeight[20] = 0.8f; + hMasa->data.importanceWeight[21] = 0.5f; + hMasa->data.importanceWeight[22] = 0.2f; + hMasa->data.importanceWeight[23] = 0.0f; + } + + if ( hMasa->config.numTwoDirBands == hMasa->config.numCodingBands ) + { + set_c( (int8_t *) hMasa->data.twoDirBands, 1, hMasa->config.numCodingBands ); + } + } + else + { + set_c( (int8_t *) hMasa->data.twoDirBands, 0, hMasa->config.numCodingBands ); + } + + for ( i = 0; i < hQMetaData->no_directions; i++ ) + { + hQMetaData->q_direction[i].cfg.nbands = hMasa->config.numCodingBands; + hQMetaData->q_direction[i].cfg.nblocks = hMasa->config.joinedSubframes == TRUE ? 1 : 4; + + if ( ivas_format == MC_FORMAT ) + { + hQMetaData->q_direction[i].cfg.mc_ls_setup = st_ivas->hEncoderConfig->mc_input_setup; + } + else + { + /* Just to be sure that this default value is maintained */ + hQMetaData->q_direction[i].cfg.mc_ls_setup = MC_LS_SETUP_INVALID; + } + } + + hQMetaData->all_coherence_zero = !hMasa->config.coherencePresent; + + ivas_set_qmetadata_maxbit_req( hQMetaData, ivas_format ); + + /* Find maximum band usable */ + maxBin = (int16_t) ( st_ivas->hEncoderConfig->input_Fs * INV_CLDFB_BANDWIDTH ); + maxBand = 0; + while ( maxBand <= MASA_FREQUENCY_BANDS && MASA_band_grouping_24[maxBand] <= maxBin ) + { + maxBand++; + } + maxBand--; + + hQMetaData->q_direction->cfg.inactiveBands = 0; + masa_total_brate = ivas_total_brate; + if ( ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + masa_total_brate = calculate_cpe_brate_MASA_ISM( st_ivas->ism_mode, ivas_total_brate, st_ivas->hEncoderConfig->nchan_ism ); + } + + if ( masa_total_brate >= IVAS_384k && ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) ) + { + int16_t continueLoop; + continueLoop = 1; + while ( maxBand > 5 && continueLoop ) + { + for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + if ( hMasa->data.energy[sf][maxBand - 1] > 100000 ) + { + continueLoop = 0; + break; + } + } + if ( continueLoop ) + { + maxBand--; + } + } + + if ( maxBand < MASA_MAXIMUM_CODING_SUBBANDS ) + { + hQMetaData->q_direction->cfg.inactiveBands = MASA_MAXIMUM_CODING_SUBBANDS - maxBand; + } + else + { + hQMetaData->q_direction->cfg.inactiveBands = 0; + } + } + + masa_sample_rate_band_correction( &( hMasa->config ), hMasa->data.band_mapping, hQMetaData, maxBand, masa_total_brate >= IVAS_384k, NULL ); + + if ( hMasa->config.numTwoDirBands >= hMasa->config.numCodingBands ) + { + hMasa->config.numTwoDirBands = hMasa->config.numCodingBands; + set_c( (int8_t *) hMasa->data.twoDirBands, 1, hMasa->config.numCodingBands ); + } + + /* Transmit stereo signals using a mono downmix at lowest bitrates */ + if ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) && st_ivas->nCPE == 1 && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL ) + { + st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = ( ivas_total_brate - ism_total_brate < MASA_STEREO_MIN_BITRATE ) ? 1 : 0; + } + + if ( ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + if ( st_ivas->hCPE[0]->element_mode == IVAS_CPE_DFT || hMasa->data.hOmasaData->omasa_stereo_sw_cnt < OMASA_STEREO_SW_CNT_MAX ) + { + hMasa->data.hOmasaData->lp_noise_CPE = st_ivas->hCPE[0]->hCoreCoder[0]->lp_noise; + } + else + { + hMasa->data.hOmasaData->lp_noise_CPE = ( st_ivas->hCPE[0]->hCoreCoder[0]->lp_noise + st_ivas->hCPE[0]->hCoreCoder[1]->lp_noise ) / CPE_CHANNELS; + } + } + + return; +} + +#endif /*-----------------------------------------------------------------------* * ivas_masa_surrcoh_signicant() diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c index a08dcea74d2b3320e378a3679107d2aa08e697c4..9590e9b4ad789c638f7c9acd1f52b19a020a00ad 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc.c @@ -128,11 +128,18 @@ ivas_error ivas_mcmasa_enc_open( } /* With McMASA, we config MASA encoder only in init as we know the input and there are no frame-by-frame changes currently. */ +#ifdef MEM_ALLOC_APP + if ( ( error = ivas_masa_enc_config_memory( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_masa_enc_config( st_ivas ) ) != IVAS_ERR_OK ) +#endif { return error; } +#ifdef MEM_ALLOC_APP + ivas_masa_enc_init( st_ivas ); +#endif /* Determine the number of bands */ hMcMasa->nbands = st_ivas->hMasa->config.numCodingBands; diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index 83c5f57c17e46b72e685477ea354e87ab2e46207..9b59eb4a9e67765adfb44ea51405c0e939aa30a5 100755 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -633,7 +633,9 @@ ivas_error ivas_mc_enc_config( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) { +#ifndef MEM_ALLOC_APP Encoder_State *st0; /* used for bitstream handling */ +#endif MC_MODE last_mc_mode; ivas_error error; @@ -644,10 +646,11 @@ ivas_error ivas_mc_enc_config( /* select MC format mode */ st_ivas->mc_mode = ivas_mc_mode_select( st_ivas->hEncoderConfig->mc_input_setup, st_ivas->hEncoderConfig->ivas_total_brate ); +#ifndef MEM_ALLOC_APP /* write MC LS setup */ st0 = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; push_indice( st0->hBstr, IND_SMODE, st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_BITS ); - +#endif /* MC format switching */ if ( st_ivas->hEncoderConfig->last_ivas_total_brate != st_ivas->hEncoderConfig->ivas_total_brate || st_ivas->mc_mode != last_mc_mode ) { diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc.c index b9bb5981cd6be64318e93e7693de4a5e040b75fc..bf0711af93ee8cad5470c414d85da6d3e7b9e130 100644 --- a/lib_enc/ivas_omasa_enc.c +++ b/lib_enc/ivas_omasa_enc.c @@ -264,6 +264,7 @@ ivas_error ivas_omasa_enc_config( return error; } +#ifndef MEM_ALLOC_APP /* re-write IVAS format signalling - actual 'ism_mode' was not known before */ if ( st_ivas->nSCE > 0 ) { @@ -275,7 +276,7 @@ ivas_error ivas_omasa_enc_config( } ivas_write_format( st_ivas ); - +#endif if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->hOMasa == NULL ) { if ( ( error = ivas_omasa_enc_open( st_ivas ) ) != IVAS_ERR_OK ) @@ -302,7 +303,11 @@ ivas_error ivas_omasa_enc_config( } /* Configure MASA encoder based on frame parameters */ +#ifdef MEM_ALLOC_APP + if ( ( error = ivas_masa_enc_config_memory( st_ivas ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_masa_enc_config( st_ivas ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 23e666a7f096a69cbc154b9d6515f4c7efea8923..9fc5c410c2af539316896962133dda0f07d88a51 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -725,6 +725,217 @@ ivas_error IVAS_ENC_ConfigureForMultichannel( } +#ifdef MEM_ALLOC_APP +/*---------------------------------------------------------------------* + * IVAS_ENC_Initialize() + * + * Initialize IVAS encoder handles and allocate the memory + *---------------------------------------------------------------------*/ + +/*! r: error code */ +ivas_error IVAS_ENC_Initialize( + IVAS_ENC_HANDLE hIvasEnc /* i/o: IVAS encoder handle */ +) +{ + Encoder_Struct *st_ivas; + ivas_error error; + + if ( hIvasEnc == NULL || hIvasEnc->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + st_ivas = hIvasEnc->st_ivas; + + if ( ( error = ivas_init_encoder( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( st_ivas->hEncoderConfig->ivas_format == MONO_FORMAT ) + { + hIvasEnc->hCoreCoder = st_ivas->hSCE[0]->hCoreCoder[0]; /* Note: this is needed for switching in EVS mono */ + } + else + { + hIvasEnc->hCoreCoder = NULL; + } + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_ENC_ReconfigureIVAS() + * + * Reconfigure IVAS encoder handles and reallocate the memory based on + * changes of 'hEncoderConfig' parameters, typically ivas_total_brate + *---------------------------------------------------------------------*/ + +/*! r: error code */ +ivas_error IVAS_ENC_Reconfigure( + IVAS_ENC_HANDLE hIvasEnc /* i/o: IVAS encoder handle */ +) +{ + Encoder_Struct *st_ivas; + ENCODER_CONFIG_HANDLE hEncoderConfig; + ENC_CORE_HANDLE hCoreCoder; + int16_t i, ch, n; + ivas_error error; + + error = IVAS_ERR_OK; + + if ( !hIvasEnc->isConfigured ) + { + return IVAS_ERR_NOT_CONFIGURED; + } + + st_ivas = hIvasEnc->st_ivas; + hEncoderConfig = st_ivas->hEncoderConfig; + hCoreCoder = hIvasEnc->hCoreCoder; + + if ( ( error = sanitizeBandwidth( hIvasEnc ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( hEncoderConfig->Opt_RF_ON && ( hEncoderConfig->ivas_total_brate != ACELP_13k20 || hEncoderConfig->input_Fs == 8000 || hEncoderConfig->max_bwidth == NB ) ) || hEncoderConfig->rf_fec_offset == 0 ) + { + if ( hEncoderConfig->ivas_total_brate == ACELP_13k20 && hEncoderConfig->ivas_format == MONO_FORMAT ) + { + st_ivas->codec_mode = MODE1; + reset_rf_indices( hCoreCoder->hRF, hCoreCoder->L_frame, &( hCoreCoder->rf_target_bits_write ) ); + } + hEncoderConfig->Opt_RF_ON = 0; + hEncoderConfig->rf_fec_offset = 0; + hIvasEnc->switchingActive = true; + } + + if ( hIvasEnc->Opt_RF_ON_loc && hIvasEnc->rf_fec_offset_loc != 0 && L_sub( hEncoderConfig->ivas_total_brate, ACELP_13k20 ) == 0 && L_sub( hEncoderConfig->input_Fs, 8000 ) != 0 && hEncoderConfig->max_bwidth != NB ) + { + st_ivas->codec_mode = MODE2; + if ( hEncoderConfig->Opt_RF_ON == 0 && hEncoderConfig->ivas_format == MONO_FORMAT ) + { + reset_rf_indices( hCoreCoder->hRF, hCoreCoder->L_frame, &( hCoreCoder->rf_target_bits_write ) ); + } + hEncoderConfig->Opt_RF_ON = 1; + hEncoderConfig->rf_fec_offset = hIvasEnc->rf_fec_offset_loc; + hIvasEnc->switchingActive = true; + } + + /* in case of 8kHz sampling rate or when in "max_band NB" mode, limit the total bitrate to 24.40 kbps */ + if ( ( ( hEncoderConfig->input_Fs == 8000 ) || ( hEncoderConfig->max_bwidth == NB ) ) && ( hEncoderConfig->ivas_total_brate > ACELP_24k40 ) ) + { + hEncoderConfig->ivas_total_brate = ACELP_24k40; + st_ivas->codec_mode = MODE2; + hIvasEnc->switchingActive = true; + } + + /*-----------------------------------------------------------------* + * Reconfigure IVAS encoder handles and reallocate the memory + * if IVAS total bitrate has changed + *-----------------------------------------------------------------*/ + + if ( hEncoderConfig->ivas_format != MONO_FORMAT ) + { + if ( ( error = ivas_reconfig_enc( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /*-----------------------------------------------------------------* + * Re-allocate and re-initialize buffer of indices if IVAS total bitrate has changed + *-----------------------------------------------------------------*/ + + if ( hEncoderConfig->ivas_total_brate != hEncoderConfig->last_ivas_total_brate ) + { + /* de-allocate old buffer of indices */ + free( st_ivas->ind_list ); + + /* set the maximum allowed number of indices in the list */ + st_ivas->ivas_max_num_indices = get_ivas_max_num_indices( hEncoderConfig->ivas_format, hEncoderConfig->ivas_total_brate ); + + /* allocate new buffer of indices */ + if ( ( st_ivas->ind_list = (INDICE_HANDLE) malloc( st_ivas->ivas_max_num_indices * sizeof( Indice ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for buffer of indices!\n" ) ); + } + + /* reset the list of indices */ + for ( i = 0; i < st_ivas->ivas_max_num_indices; i++ ) + { + st_ivas->ind_list[i].nb_bits = -1; + } + + /* de-allocate old buffer of metadata indices */ + if ( st_ivas->ind_list_metadata != NULL ) + { + free( st_ivas->ind_list_metadata ); + } + + /* set the maximum allowed number of metadata indices in the list */ + st_ivas->ivas_max_num_indices_metadata = get_ivas_max_num_indices_metadata( hEncoderConfig->ivas_format, hEncoderConfig->ivas_total_brate ); + + if ( st_ivas->ivas_max_num_indices_metadata > 0 ) + { + /* allocate new buffer of metadata indices */ + if ( ( st_ivas->ind_list_metadata = (INDICE_HANDLE) malloc( st_ivas->ivas_max_num_indices_metadata * sizeof( Indice ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for buffer of metadata indices!\n" ) ); + } + + /* reset the list of metadata indices */ + for ( i = 0; i < st_ivas->ivas_max_num_indices_metadata; i++ ) + { + st_ivas->ind_list_metadata[i].nb_bits = -1; + } + } + else + { + st_ivas->ind_list_metadata = NULL; + } + + /* set pointers to the new buffers of indices in each element */ + for ( n = 0; n < st_ivas->nSCE; n++ ) + { + st_ivas->hSCE[n]->hCoreCoder[0]->hBstr->ind_list = st_ivas->ind_list; + st_ivas->hSCE[n]->hCoreCoder[0]->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; + + if ( st_ivas->hSCE[n]->hMetaData != NULL ) + { + st_ivas->hSCE[n]->hMetaData->ind_list = st_ivas->ind_list_metadata; + st_ivas->hSCE[n]->hMetaData->ivas_ind_list_zero = &st_ivas->ind_list_metadata; + } + } + + for ( n = 0; n < st_ivas->nCPE; n++ ) + { + for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + st_ivas->hCPE[n]->hCoreCoder[ch]->hBstr->ind_list = st_ivas->ind_list; + st_ivas->hCPE[n]->hCoreCoder[ch]->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; + } + + if ( st_ivas->hCPE[n]->hMetaData != NULL ) + { + st_ivas->hCPE[n]->hMetaData->ind_list = st_ivas->ind_list_metadata; + st_ivas->hCPE[n]->hMetaData->ivas_ind_list_zero = &st_ivas->ind_list_metadata; + } + } + } + + if ( hIvasEnc->switchingActive && hEncoderConfig->ivas_format == MONO_FORMAT ) + { + copy_encoder_config( st_ivas, hCoreCoder, 0 ); + hEncoderConfig->last_ivas_total_brate = hEncoderConfig->ivas_total_brate; + } + + return IVAS_ERR_OK; +} +#endif + + /*---------------------------------------------------------------------* * configureEncoder() * @@ -1005,6 +1216,7 @@ static ivas_error configureEncoder( return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "'-binaural' option is supported only with '-stereo' or '-stereo_dmx_evs'" ); } +#ifndef MEM_ALLOC_APP /*-----------------------------------------------------------------* * Finalize initialization *-----------------------------------------------------------------*/ @@ -1022,7 +1234,12 @@ static ivas_error configureEncoder( { hIvasEnc->hCoreCoder = NULL; } +#else + /*-----------------------------------------------------------------* + * Final updates + *-----------------------------------------------------------------*/ +#endif hIvasEnc->Opt_RF_ON_loc = hEncoderConfig->Opt_RF_ON; hIvasEnc->rf_fec_offset_loc = hEncoderConfig->rf_fec_offset; @@ -1149,7 +1366,9 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( ENCODER_CONFIG_HANDLE hEncoderConfig; ENC_CORE_HANDLE hCoreCoder; int16_t i; +#ifndef MEM_ALLOC_APP int16_t n, ch; +#endif ivas_error error; error = IVAS_ERR_OK; @@ -1168,10 +1387,12 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( return IVAS_ERR_INVALID_INPUT_BUFFER_SIZE; } +#ifndef MEM_ALLOC_APP if ( ( error = sanitizeBandwidth( hIvasEnc ) ) != IVAS_ERR_OK ) { return error; } +#endif if ( hEncoderConfig->ivas_format == ISM_FORMAT ) { @@ -1185,6 +1406,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( resetIsmMetadataProvidedFlags( hIvasEnc ); } +#ifndef MEM_ALLOC_APP if ( ( hEncoderConfig->Opt_RF_ON && ( hEncoderConfig->ivas_total_brate != ACELP_13k20 || hEncoderConfig->input_Fs == 8000 || hEncoderConfig->max_bwidth == NB ) ) || hEncoderConfig->rf_fec_offset == 0 ) { if ( hEncoderConfig->ivas_total_brate == ACELP_13k20 && hEncoderConfig->ivas_format == MONO_FORMAT ) @@ -1304,6 +1526,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( hEncoderConfig->last_ivas_total_brate = hEncoderConfig->ivas_total_brate; } +#endif /* run the main encoding routine */ if ( hEncoderConfig->ivas_format == MONO_FORMAT ) /* EVS mono */ { diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index 2f40c1ab1beda5b883618dbd755b2a68076989f0..bf8c7fcc817b38ac3053ad9f8c0673acc92e4fc9 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -271,6 +271,19 @@ void IVAS_ENC_Close( IVAS_ENC_HANDLE *phIvasEnc /* i/o: pointer to IVAS encoder handle */ ); +#ifdef MEM_ALLOC_APP +/*! r: error code */ +ivas_error IVAS_ENC_Initialize( + IVAS_ENC_HANDLE hIvasEnc /* i/o: IVAS encoder handle */ +); + +/*! r: error code */ +ivas_error IVAS_ENC_Reconfigure( + IVAS_ENC_HANDLE hIvasEnc /* i/o: IVAS encoder handle */ +); +#endif + + /* Encoding functions - should be called with a configured encoder handle */ /*! r: error code */