diff --git a/lib_com/options.h b/lib_com/options.h index ffce5fe72a773cc2ed9ffe35b9fc5441a7ab32ed..d2b08ca6d918fa34129c8bfef7acd5ac5ac99c41 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -173,6 +173,7 @@ #define NONBE_FIX_1176_OSBA_REVERB_JBM_ASAN_ERROR /* Ericsson: Issue 1176, fix in TDREND_firfilt for subframes shorter than the filter length */ #define NONBE_1240_FIX_CORE_SELECTION_ISM_SW /* VA: issue 1240: Remove the forcing of the TCX core in ISM when switching from a high bitarte to a low one */ #define NONBE_1211_DTX_BR_SWITCHING /* VA: issue 1211: fix crash in MASA DTX bitrate switching */ +#define NONBE_1217_INIT_OBJ_EDIT /* VA: issue 1217: do object editing only when objects metadata is available */ /* ##################### End NON-BE switches ########################### */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 231b4efc6098d0694057eedafae7ffe604c19c09..a9abea31159f3c9e7c28207d9304e14c92003255 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -1215,12 +1215,132 @@ ivas_error IVAS_DEC_GetEditableParameters( ) { int16_t dirac_read_idx, obj; +#ifdef NONBE_1217_INIT_OBJ_EDIT + Decoder_Struct *st_ivas; + ISM_MODE ism_mode; +#endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasEditableParameters == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef NONBE_1217_INIT_OBJ_EDIT + st_ivas = hIvasDec->st_ivas; + ism_mode = st_ivas->ism_mode; + + if ( !( st_ivas->ivas_format == ISM_FORMAT || + st_ivas->ivas_format == SBA_ISM_FORMAT || + st_ivas->ivas_format == MASA_ISM_FORMAT || + ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) ) + { + return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing is not supported in this operation mode." ); + } + + hIvasEditableParameters->gain_bed = 1.0f; + hIvasEditableParameters->num_obj = st_ivas->nchan_ism; + if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) + { + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hIsmMetaData[obj]->azimuth; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hIsmMetaData[obj]->elevation; + hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; + hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } + + if ( ism_mode == ISM_SBA_MODE_DISC ) + { + hIvasEditableParameters->gain_bed = 1.0f; + } + } + else if ( ism_mode == ISM_MODE_PARAM ) + { + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hParamIsmDec->azimuth_values[obj]; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hParamIsmDec->elevation_values[obj]; + hIvasEditableParameters->ism_metadata[obj].yaw = 0.0f; + hIvasEditableParameters->ism_metadata[obj].pitch = 0.0f; + hIvasEditableParameters->ism_metadata[obj].radius = 0.0f; + hIvasEditableParameters->ism_metadata[obj].gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = 0; + } + } + else if ( ism_mode == ISM_MODE_NONE ) + { + hIvasEditableParameters->num_obj = 0; + } +#ifdef DEBUGGING + else + { + assert( 0 && "This should never happen!" ); + } +#endif + } + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT || ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) + { + /* object editing possible only in two highest OMASA modes */ + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hIsmMetaData[obj]->azimuth; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hIsmMetaData[obj]->elevation; + hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; + + /* reset the otherwise unused "gain" field for the object */ + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } + } + else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + /* Handle MONO output */ + if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) + { + dirac_read_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->subframes_rendered]; + } + else + { + dirac_read_idx = 0; + } + + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx]; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx]; + + hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; + + /* reset the otherwise unused "gain" field for the object */ + hIvasDec->st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } + } + else if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_MODE_NONE ) + { + hIvasEditableParameters->num_obj = 0; + } +#ifdef DEBUGGING + else + { + assert( 0 && "This should never happen!" ); + } +#endif + } +#else if ( !( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT || hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT || @@ -1327,6 +1447,7 @@ ivas_error IVAS_DEC_GetEditableParameters( } } } +#endif return IVAS_ERR_OK; } @@ -1344,12 +1465,228 @@ ivas_error IVAS_DEC_SetEditableParameters( ) { int16_t dirac_read_idx, obj; +#ifdef NONBE_1217_INIT_OBJ_EDIT + Decoder_Struct *st_ivas; + ISM_MODE ism_mode; if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + st_ivas = hIvasDec->st_ivas; + ism_mode = st_ivas->ism_mode; + + if ( !( st_ivas->ivas_format == ISM_FORMAT || + st_ivas->ivas_format == SBA_ISM_FORMAT || + st_ivas->ivas_format == MASA_ISM_FORMAT || + ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) ) + { + return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing no supported in this operation mode." ); + } + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + +#ifdef DEBUGGING + assert( hIvasEditableParameters.num_obj == st_ivas->nchan_ism ); +#endif + + if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) + { + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + { + st_ivas->hIsmMetaData[obj]->edited_azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; + st_ivas->hIsmMetaData[obj]->edited_elevation = hIvasEditableParameters.ism_metadata[obj].elevation; + st_ivas->hIsmMetaData[obj]->edited_radius = hIvasEditableParameters.ism_metadata[obj].radius; + + st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + + st_ivas->hIsmMetaData[obj]->edited_yaw = hIvasEditableParameters.ism_metadata[obj].yaw; + st_ivas->hIsmMetaData[obj]->edited_pitch = hIvasEditableParameters.ism_metadata[obj].pitch; + + st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; + } + + if ( ism_mode == ISM_SBA_MODE_DISC ) + { + st_ivas->hSbaIsmData->gain_bed = hIvasEditableParameters.gain_bed; + } + } + else if ( ism_mode == ISM_MODE_PARAM ) + { + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + { + st_ivas->hParamIsmDec->edited_azimuth_values[obj] = hIvasEditableParameters.ism_metadata[obj].azimuth; + st_ivas->hParamIsmDec->edited_elevation_values[obj] = hIvasEditableParameters.ism_metadata[obj].elevation; + st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; + + /* Detect direction editing in Param-ISM mode */ + if ( fabsf( st_ivas->hParamIsmDec->azimuth_values[obj] - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || + fabsf( st_ivas->hParamIsmDec->elevation_values[obj] - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) + { + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; + } + + /* Detect gain editing in Param-ISM mode */ + if ( fabsf( 1.0f - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) + { + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; + } + } + + /* MASA is not present with the ISM format */ + st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; + } + else if ( ism_mode == ISM_MODE_NONE ) + { + if ( hIvasEditableParameters.num_obj != 0 ) + { + return IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED; + } + } +#ifdef DEBUGGING + else + { + assert( 0 && "This should never happen!" ); + } +#endif + } + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_DISC ) ) + { + int16_t id_th; + float threshold_azi, threshold_ele; + + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + { + if ( st_ivas->hMasaIsmData != NULL ) + { + /* copy relevant fields also to OMASA structs, but only if the value has been changed. original values are in st_ivas->hIsmMetaData */ + /* first, need to convert float values to ints used internally */ + int16_t new_azi, new_ele; + if ( hIvasEditableParameters.ism_metadata[obj].azimuth > 0.0f ) + { + new_azi = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].azimuth + 0.5f ); + } + else + { + new_azi = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].azimuth - 0.5f ); + } + + if ( hIvasEditableParameters.ism_metadata[obj].elevation > 0.0f ) + { + new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation + 0.5f ); + } + else + { + new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation - 0.5f ); + } + + if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + /* Handle MONO output */ + if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) + { + dirac_read_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->subframes_rendered]; + } + else + { + dirac_read_idx = 0; + } + + /* determine thresholds for detecting object metadata edit for direction based on quantization resolution of the spatial direction parameters. + * these depend from the number of bits used to transmit the directions, + * which in turn depends from the object priority and importance: + * importance -> priority -> number of bits -> elevation resolution -> elevation ring index -> azimuth resolution. + * leading to elevation_resolution -> elevation threshold and azimuth resolution -> azimuth threshold */ + id_th = (int16_t) ( fabsf( (float) st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) / delta_theta_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 3] + 0.5f ); + threshold_azi = 360.0f / (float) no_phi_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 1][id_th]; + threshold_ele = delta_theta_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 3]; + + if ( ( (float) abs( new_azi - st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx] ) > threshold_azi ) || + ( (float) abs( new_ele - st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) > threshold_ele ) ) + { + /* at least one of the threshold is exceeded, so use new direction value and set editing detection flag */ + st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; + st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; + } + } + else + { + /* detect editing in ISM_MASA_MODE_DISC. optionally, add quantization-resolution -based thresholds */ + if ( fabsf( st_ivas->hIsmMetaData[obj]->azimuth - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || + fabsf( st_ivas->hIsmMetaData[obj]->elevation - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) + { + st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; + st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; + } + } + + /* compare pre-edit gain and the edited one to detect editing */ + if ( fabsf( st_ivas->hIsmMetaData[obj]->edited_gain - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) + { + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; + } + else + { + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; + } + } + + /* Copy edited values to hIsmMetaData struct */ + if ( st_ivas->hIsmMetaData[obj] != NULL ) + { + st_ivas->hIsmMetaData[obj]->azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; + st_ivas->hIsmMetaData[obj]->elevation = hIvasEditableParameters.ism_metadata[obj].elevation; + st_ivas->hIsmMetaData[obj]->yaw = hIvasEditableParameters.ism_metadata[obj].yaw; + st_ivas->hIsmMetaData[obj]->pitch = hIvasEditableParameters.ism_metadata[obj].pitch; + st_ivas->hIsmMetaData[obj]->radius = hIvasEditableParameters.ism_metadata[obj].radius; + st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; + } + } + + if ( fabsf( hIvasEditableParameters.gain_bed - 1.0f ) > OMASA_GAIN_EDIT_THR ) + { + st_ivas->hMasaIsmData->gain_masa_edited = hIvasEditableParameters.gain_bed; + st_ivas->hMasaIsmData->masa_gain_is_edited = 1u; + } + else + { + st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; + } + } +#else + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + if ( !( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT || hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT || @@ -1552,6 +1889,7 @@ ivas_error IVAS_DEC_SetEditableParameters( hIvasDec->st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; } } +#endif return IVAS_ERR_OK; }