diff --git a/apps/renderer.c b/apps/renderer.c index c2fb6add8a680642a7ec9715170e078936499cee..62132c754acc7f49129192a1847f86d506b220ad 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -965,7 +965,12 @@ int main( } else { +#ifdef FIX_379_EXT_METADATA + error = IVAS_REND_SetHeadRotation( hIvasRend, NULL, NULL ); + if ( ( error != IVAS_ERR_OK ) && ( error != IVAS_ERR_INVALID_OUTPUT_FORMAT ) ) // VE: TBC +#else if ( ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, NULL, NULL ) ) != IVAS_ERR_OK ) && ( IVAS_REND_SetHeadRotation( hIvasRend, NULL, NULL ) != IVAS_ERR_INVALID_OUTPUT_FORMAT ) ) // VE: TBC +#endif { fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 1da32f21450dc95991af72f32a654008b8bcddc7..d7674b43735d439a5971a67f013fbe8567b6f29c 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -320,11 +320,14 @@ typedef enum #define ISM_Q_STEP 2.5f #define ISM_Q_STEP_BORDER 5.0f -#define ISM_RADIUS_NBITS 6 -#define ISM_RADIUS_MIN 0.0f -#define ISM_RADIUS_DELTA 0.25f /* Max radius = (2^ISM_RADIUS_NBITS-1)*0.25 = 15.75 */ -#define ISM_EXTENDED_METADATA_BRATE IVAS_64k -#define ISM_EXTENDED_METADATA_BITS 1 +#define ISM_RADIUS_NBITS 6 +#define ISM_RADIUS_MIN 0.0f +#define ISM_RADIUS_DELTA 0.25f /* Max radius = (2^ISM_RADIUS_NBITS-1)*0.25 = 15.75 */ +#define ISM_EXTENDED_METADATA_BRATE IVAS_64k +#define ISM_EXTENDED_METADATA_BITS 1 +#ifdef FIX_379_EXT_METADATA +#define ISM_METADATA_RS_MAX_FRAMES 5 /* Number of frames with opposite extended metadata flags before switching */ +#endif /* Parametric ISM */ #define MAX_PARAM_ISM_NBANDS 11 @@ -373,7 +376,11 @@ enum { IND_ISM_NUM_OBJECTS, IND_ISM_EXTENDED_FLAG = IND_ISM_NUM_OBJECTS + MAX_NUM_OBJECTS, +#ifdef FIX_379_EXT_METADATA + IND_ISM_METADATA_FLAG, +#else IND_ISM_METADATA_FLAG = IND_ISM_EXTENDED_FLAG + MAX_NUM_OBJECTS, /* EN2VE: Is this not supposed to be in the loop part below, since it is one per ISM? */ +#endif IND_ISM_VAD_FLAG = IND_ISM_METADATA_FLAG + MAX_NUM_OBJECTS, #ifdef DISCRETE_ISM_DTX_CNG IND_ISM_NOISY_SPEECH_FLAG = IND_ISM_VAD_FLAG + MAX_NUM_OBJECTS, diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 2aab3dd7ee7c539233ca2a06a77ff81068d70af9..21ea995a84452ea590cd4d04d8bbbb825d5d06c4 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -836,12 +836,18 @@ ivas_error ivas_ism_metadata_dec( ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ SCE_DEC_HANDLE hSCE[], /* i/o: SCE decoder handles */ const int16_t bfi, /* i : bfi flag */ - int16_t nb_bits_metadata[], /* o : number of metadata bits */ + int16_t nb_bits_metadata[], /* o : number of metadata bits */ ISM_MODE ism_mode, /* i : ISM mode */ #ifdef DISCRETE_ISM_DTX_CNG ISM_DTX_DATA_DEC hISMDTX, /* i/o: ISM DTX structure */ #endif +#ifdef FIX_379_EXT_METADATA + const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Config Handle */ + int16_t *ism_extended_metadata_flag, /* i/o: Extended metadata active in renderer */ + int16_t *ism_extmeta_cnt /* i/o: Number of change frames observed */ +#else const PARAM_ISM_CONFIG_HANDLE hParamIsm /* i : Param ISM Config Handle */ +#endif ); diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index eedb65dbf3b400ed2af8ea4070a8fde86954b419..041a589ee3895ad58bd43132559a1ff3e966d14d 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -43,7 +43,15 @@ /*----------------------------------------------------------------------------------* * Declaration of ISM common (encoder & decoder) structure *----------------------------------------------------------------------------------*/ - +#ifdef FIX_379_ANGLE +typedef struct +{ + int16_t last_angle1_idx; /* last frame index of coded azimuth/yaw */ + int16_t angle1_diff_cnt; /* FEC counter of consecutive differentially azimuth/yaw coded frames */ + int16_t last_angle2_idx; /* last frame index of coded elevation/pitch */ + int16_t angle2_diff_cnt; /* FEC counter of consecutive differentially elevation/pitch coded frames */ +} ISM_METADATA_ANGLE, *ISM_METADATA_ANGLE_HANDLE; +#else typedef struct { int16_t last_azimuth_idx; /* last frame index of coded azimuth */ @@ -52,7 +60,7 @@ typedef struct int16_t elevation_diff_cnt; /* FEC counter of consecutive differentially elevation coded frames */ } ISM_METADATA_ANGLE, *ISM_METADATA_ANGLE_HANDLE; - +#endif /* ISM metadata handle (storage for one frame of read ISM metadata) */ typedef struct { @@ -62,11 +70,16 @@ typedef struct float azimuth; /* azimuth value read from the input metadata file */ float elevation; /* azimuth value read from the input metadata file */ float radius; - float yaw; /* azimuth orientation value read from the input metadata file */ - float pitch; /* elevation orientation value read from the input metadata file */ + float yaw; /* azimuth orientation value read from the input metadata file */ + float pitch; /* elevation orientation value read from the input metadata file */ +#ifdef FIX_379_ANGLE + ISM_METADATA_ANGLE position_angle; /* Angle structs for azimuth and elevation */ + ISM_METADATA_ANGLE orientation_angle; /* Angle structs for yaw and pitch */ +#else ISM_METADATA_ANGLE angle[2]; /* Angle structs for [0] azimuth/elevation and [1] yaw/pitch */ - int16_t last_radius_idx; /* last frame index of coded radius */ - int16_t radius_diff_cnt; /* FEC counter of consecutive differentially radius coded frames */ +#endif + int16_t last_radius_idx; /* last frame index of coded radius */ + int16_t radius_diff_cnt; /* FEC counter of consecutive differentially radius coded frames */ #ifdef DISCRETE_ISM_DTX_CNG float last_azimuth; /* MD smoothing in DTX- last Q azimuth value */ diff --git a/lib_com/options.h b/lib_com/options.h index 6d97909f18b4173d46f2b1a00701f1fd7613292e..43de30fbeb4eb3ca394b32a526722d5189c9e721 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -152,6 +152,9 @@ #define FIX_382_MASA_META_FRAMING_ASYNC /* Nokia: Issue 382: detect potential MASA metadata framing offset */ #define SBA2MONO /* FhG: Issue 365: Adapt processing of SBA mono output to be in line with stereo output (less delay, lower complexity) */ +#define FIX_379_EXT_METADATA /* Eri: Extended metadata issues */ +#define FIX_379_ANGLE /* Eri: Extended metadata issues related to angle structure */ + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index f89a64bf3e7792eada58a65c39903b0f25d94f8d..8eb822a32ef7ebede16f5d0a7b89d5f873b712c3 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -152,38 +152,70 @@ ivas_error ivas_dec( // VE: call ivas_ism_metadata_dec() with 'st_ivas' - TBD #ifdef DISCRETE_ISM_DTX_CNG #ifdef NCHAN_ISM_PARAMETER +#ifdef FIX_379_EXT_METADATA + if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, st_ivas->hDirAC->hParamIsm, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, st_ivas->hDirAC->hParamIsm ) ) != IVAS_ERR_OK ) +#endif +#else +#ifdef FIX_379_EXT_METADATA + if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, st_ivas->hDirAC->hParamIsm, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, st_ivas->hDirAC->hParamIsm ) ) != IVAS_ERR_OK ) +#endif #endif { return error; } #else #ifdef NCHAN_ISM_PARAMETER +#ifdef FIX_379_EXT_METADATA + ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hDirAC->hParamIsm, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt ); +#else ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hDirAC->hParamIsm ); +#endif +#else +#ifdef FIX_379_EXT_METADATA + ivas_ism_metadata_dec( ivas_total_brate, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hDirAC->hParamIsm, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt ); #else ivas_ism_metadata_dec( ivas_total_brate, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hDirAC->hParamIsm ); #endif +#endif #endif } else /* ISM_MODE_DISC */ { #ifdef DISCRETE_ISM_DTX_CNG #ifdef NCHAN_ISM_PARAMETER +#ifdef FIX_379_EXT_METADATA + if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL ) ) != IVAS_ERR_OK ) +#endif +#else +#ifdef FIX_379_EXT_METADATA + if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL ) ) != IVAS_ERR_OK ) +#endif #endif { return error; } #else #ifdef NCHAN_ISM_PARAMETER +#ifdef FIX_379_EXT_METADATA + ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt ); +#else ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, NULL ); +#endif +#else +#ifdef FIX_379_EXT_METADATA + ivas_ism_metadata_dec( ivas_total_brate, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt ); #else ivas_ism_metadata_dec( ivas_total_brate, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, NULL ); #endif +#endif #endif } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index e53218d3e70ff0bb9b70b5e1524d6c17ebb9635e..73f2acb2db6aa3aee5716ff1f2ecf4d090dd2a92 100755 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -888,6 +888,10 @@ ivas_error ivas_init_decoder( st_ivas->nSCE = st_ivas->nchan_transport; /* "st_ivas->nchan_transport" is known from ivas_dec_setup */ st_ivas->nCPE = 0; +#ifdef FIX_379_EXT_METADATA + st_ivas->ism_extmeta_active = -1; + st_ivas->ism_extmeta_cnt = 0; +#endif if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index 75b9164e1dc34f33603c748a6dce1bd8d26c18e4..feccbc9766a28230619be030a1710d57607d6613 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -154,18 +154,35 @@ ivas_error ivas_ism_metadata_dec( #ifdef DISCRETE_ISM_DTX_CNG ISM_DTX_DATA_DEC hISMDTX, /* i/o: ISM DTX structure */ #endif +#ifdef FIX_379_EXT_METADATA + const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Config Handle */ + int16_t *ism_extmeta_active, /* i/o: Extended metadata active in renderer*/ + int16_t *ism_extmeta_cnt /* i/o: Number of change frames observed*/ +#else const PARAM_ISM_CONFIG_HANDLE hParamIsm /* i : Param ISM Config Handle */ +#endif ) { int16_t ch, nb_bits_start = 0, last_bit_pos; int16_t idx_radius; int32_t element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS]; DEC_CORE_HANDLE st0; +#ifdef FIX_379_EXT_METADATA + int16_t ism_extmeta_bitstream; + float yaw, pitch, radius; +#else int16_t ism_extended_metadata_flag; +#endif int16_t flag_abs_radius; int16_t flag_abs_orientation; +#ifdef FIX_379_ANGLE + int16_t flag_abs_position; + int16_t idx_angle1; + int16_t idx_angle2; +#else int16_t idx_azimuth, flag_abs_azimuth; int16_t idx_elevation; +#endif int16_t next_bit_pos_orig; uint16_t i, bstr_meta[MAX_BITS_METADATA], *bstr_orig; ISM_METADATA_HANDLE hIsmMetaData; @@ -218,7 +235,11 @@ ivas_error ivas_ism_metadata_dec( bstr_orig = st0->bit_stream; next_bit_pos_orig = st0->next_bit_pos; st0->next_bit_pos = 0; +#ifdef FIX_379_EXT_METADATA + ism_extmeta_bitstream = 0; +#else ism_extended_metadata_flag = 0; +#endif /* reverse the bitstream for easier reading of indices */ for ( i = 0; i < min( MAX_BITS_METADATA, last_bit_pos ); i++ ) @@ -270,8 +291,29 @@ ivas_error ivas_ism_metadata_dec( /* read extended metadata presence flag */ if ( ism_total_brate >= ISM_EXTENDED_METADATA_BRATE ) { +#ifdef FIX_379_EXT_METADATA + ism_extmeta_bitstream = get_next_indice( st0, ISM_EXTENDED_METADATA_BITS ); +#else ism_extended_metadata_flag = get_next_indice( st0, ISM_EXTENDED_METADATA_BITS ); +#endif } +#ifdef FIX_379_EXT_METADATA + /* Apply hysteresis in case rate switching causes fluctuation in presence of extended metadata */ + if ( *ism_extmeta_active == -1 || *ism_extmeta_active == ism_extmeta_bitstream ) /* If first frame or bitstream matches internal state */ + { + *ism_extmeta_active = ism_extmeta_bitstream; + *ism_extmeta_cnt = 0; + } + else + { + ( *ism_extmeta_cnt )++; + if ( *ism_extmeta_cnt == ISM_METADATA_RS_MAX_FRAMES ) /* ISM_METADATA_RS_MAX_FRAMES change frames observed - update state */ + { + *ism_extmeta_active = ism_extmeta_bitstream; + *ism_extmeta_cnt = 0; + } + } +#endif /* Read ISM present flags (one per object) */ for ( ch = 0; ch < *nchan_transport; ch++ ) @@ -330,44 +372,102 @@ ivas_error ivas_ism_metadata_dec( { nb_bits_start = st0->next_bit_pos; } - +#ifdef FIX_379_ANGLE + flag_abs_position = 0; +#else flag_abs_azimuth = 0; +#endif flag_abs_orientation = 0; flag_abs_radius = 0; if ( hIsmMeta[ch]->ism_metadata_flag ) { +#ifdef FIX_379_ANGLE + decode_angle_indices( st0, &( hIsmMetaData->position_angle ), &flag_abs_position ); + idx_angle1 = hIsmMetaData->position_angle.last_angle1_idx; + idx_angle2 = hIsmMetaData->position_angle.last_angle2_idx; +#else decode_angle_indices( st0, &( hIsmMetaData->angle[0] ), &flag_abs_azimuth ); idx_azimuth = hIsmMetaData->angle[0].last_azimuth_idx; idx_elevation = hIsmMetaData->angle[0].last_elevation_idx; - +#endif /* Azimuth/Elevation dequantization */ if ( ism_mode == ISM_MODE_PARAM ) { +#ifdef FIX_379_ANGLE + hParamIsm->azi_index[ch] = idx_angle1; + hParamIsm->ele_index[ch] = idx_angle2; +#else hParamIsm->azi_index[ch] = idx_azimuth; hParamIsm->ele_index[ch] = idx_elevation; +#endif } else /* ISM_MODE_DISC */ { +#ifdef FIX_379_ANGLE + hIsmMetaData->azimuth = ism_dequant_meta( idx_angle1, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); + hIsmMetaData->elevation = ism_dequant_meta( idx_angle2, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); +#else hIsmMetaData->azimuth = ism_dequant_meta( idx_azimuth, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); hIsmMetaData->elevation = ism_dequant_meta( idx_elevation, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); +#endif /* radius/raw/pitch dequantization */ +#ifdef FIX_379_EXT_METADATA + if ( ism_extmeta_bitstream ) +#else if ( ism_extended_metadata_flag ) +#endif { +#ifdef FIX_379_ANGLE + decode_angle_indices( st0, &( hIsmMetaData->orientation_angle ), &flag_abs_orientation ); + idx_angle1 = hIsmMetaData->orientation_angle.last_angle1_idx; + idx_angle2 = hIsmMetaData->orientation_angle.last_angle2_idx; +#else decode_angle_indices( st0, &( hIsmMetaData->angle[1] ), &flag_abs_orientation ); idx_azimuth = hIsmMetaData->angle[1].last_azimuth_idx; idx_elevation = hIsmMetaData->angle[1].last_elevation_idx; - +#endif +#ifdef FIX_379_EXT_METADATA +#ifdef FIX_379_ANGLE + yaw = ism_dequant_meta( idx_angle1, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); + pitch = ism_dequant_meta( idx_angle2, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); +#else + yaw = ism_dequant_meta( idx_azimuth, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); + pitch = ism_dequant_meta( idx_elevation, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); +#endif +#else hIsmMetaData->yaw = ism_dequant_meta( idx_azimuth, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); hIsmMetaData->pitch = ism_dequant_meta( idx_elevation, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); +#endif idx_radius = decode_radius( st0, &hIsmMetaData->last_radius_idx, &flag_abs_radius ); +#ifdef FIX_379_EXT_METADATA + radius = usdequant( idx_radius, ISM_RADIUS_MIN, ISM_RADIUS_DELTA ); +#else hIsmMetaData->radius = usdequant( idx_radius, ISM_RADIUS_MIN, ISM_RADIUS_DELTA ); +#endif +#ifdef FIX_379_EXT_METADATA + if ( *ism_extmeta_active == 1 ) + { + hIsmMetaData->yaw = yaw; + hIsmMetaData->pitch = pitch; + hIsmMetaData->radius = radius; + } +#endif } else { +#ifdef FIX_379_EXT_METADATA + if ( *ism_extmeta_active == 0 ) + { + hIsmMetaData->yaw = 0.0f; + hIsmMetaData->pitch = 0.0f; + hIsmMetaData->radius = 1.0f; + } +#else hIsmMetaData->radius = 1.0f; +#endif } } #ifdef DISCRETE_ISM_DTX_CNG @@ -461,8 +561,13 @@ ivas_error ivas_ism_metadata_dec( { hParamIsm->azi_index[ch] = hParamIsm->azi_index[ch] + hParamIsm->last_az_sgn[ch] * hParamIsm->last_az_diff[ch]; hParamIsm->ele_index[ch] = hParamIsm->ele_index[ch] + hParamIsm->last_el_sgn[ch] * hParamIsm->last_el_diff[ch]; +#ifdef FIX_379_ANGLE + hIsmMeta[ch]->position_angle.last_angle1_idx = hParamIsm->azi_index[ch]; + hIsmMeta[ch]->position_angle.last_angle2_idx = hParamIsm->ele_index[ch]; +#else hIsmMeta[ch]->angle[0].last_azimuth_idx = hParamIsm->azi_index[ch]; hIsmMeta[ch]->angle[0].last_elevation_idx = hParamIsm->ele_index[ch]; +#endif } } } @@ -576,10 +681,17 @@ ivas_error ivas_ism_metadata_dec_create( } st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0; +#ifdef FIX_379_ANGLE + st_ivas->hIsmMetaData[ch]->position_angle.last_angle1_idx = 0; + st_ivas->hIsmMetaData[ch]->position_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); + st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle1_idx = 0; + st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); +#else st_ivas->hIsmMetaData[ch]->angle[0].last_azimuth_idx = 0; st_ivas->hIsmMetaData[ch]->angle[0].last_elevation_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); st_ivas->hIsmMetaData[ch]->angle[1].last_azimuth_idx = 0; st_ivas->hIsmMetaData[ch]->angle[1].last_elevation_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); +#endif st_ivas->hIsmMetaData[ch]->last_radius_idx = 8; /* Init to radius 1.0 */ #ifdef DISCRETE_ISM_DTX_CNG @@ -608,6 +720,148 @@ ivas_error ivas_ism_metadata_dec_create( * * Decoding of an angle *-------------------------------------------------------------------------*/ +#ifdef FIX_379_ANGLE + +static void decode_angle_indices( + DEC_CORE_HANDLE st0, /* i/o: bitstream handle */ + ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle */ + int16_t *flag_abs_angle1 /* o : Azimuth/yaw encoding mode */ +) +{ + int16_t idx_angle1, nbits_diff_angle1, diff, sgn; + int16_t idx_angle2, nbits_diff_angle2; + + /*----------------------------------------------------------------* + * Azimuth/yaw decoding and dequantization + *----------------------------------------------------------------*/ + + /* Decode azimuth/yaw index */ + if ( get_next_indice( st0, 1 ) == 1 ) /* azimuth_abs_flag */ + { + idx_angle1 = get_next_indice( st0, ISM_AZIMUTH_NBITS ); + *flag_abs_angle1 = 1; + } + else + { + diff = 0; + sgn = 1; + + if ( get_next_indice( st0, 1 ) == 0 ) + { + nbits_diff_angle1 = 1; + } + else + { + nbits_diff_angle1 = 1; + + if ( get_next_indice( st0, 1 ) == 1 ) /* negative sign */ + { + sgn = -1; + } + + nbits_diff_angle1++; + + /* read until the stop bit */ + while ( ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 ) && ( get_next_indice( st0, 1 ) == 1 ) ) + { + diff++; + nbits_diff_angle1++; + } + + if ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 ) + { + /* count stop bit */ + nbits_diff_angle1++; + } + } + idx_angle1 = angle->last_angle1_idx + sgn * diff; + } + + /* azimuth/yaw is on a circle - check for diff coding for -180° -> 180° and vice versa changes */ + if ( idx_angle1 > ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) + { + idx_angle1 -= ( 1 << ISM_AZIMUTH_NBITS ) - 1; /* +180° -> -180° */ + } + else if ( idx_angle1 < 0 ) + { + idx_angle1 += ( 1 << ISM_AZIMUTH_NBITS ) - 1; /* -180° -> +180° */ + } + + /* +180° == -180° */ + if ( idx_angle1 == ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) + { + idx_angle1 = 0; + } + + /* sanity check in case of FER or BER */ + if ( idx_angle1 < 0 || idx_angle1 > ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) + { + idx_angle1 = angle->last_angle1_idx; + } + + /*----------------------------------------------------------------* + * Elevation/pitch decoding and dequantization + *----------------------------------------------------------------*/ + + /* Decode elevation/pitch index */ + if ( *flag_abs_angle1 == 0 && get_next_indice( st0, 1 ) == 1 ) /* elevation_abs_flag */ + { + idx_angle2 = get_next_indice( st0, ISM_ELEVATION_NBITS ); + } + else + { + diff = 0; + sgn = 1; + + if ( get_next_indice( st0, 1 ) == 0 ) + { + nbits_diff_angle2 = 1; + } + else + { + nbits_diff_angle2 = 1; + + if ( get_next_indice( st0, 1 ) == 1 ) /* negative sign */ + { + sgn = -1; + } + + nbits_diff_angle2++; + + /* read until the stop bit */ + while ( ( nbits_diff_angle2 < ISM_ELEVATION_NBITS ) && ( get_next_indice( st0, 1 ) == 1 ) ) + { + diff++; + nbits_diff_angle2++; + } + + if ( nbits_diff_angle2 < ISM_ELEVATION_NBITS ) + { + /* count stop bit */ + nbits_diff_angle2++; + } + } + + idx_angle2 = angle->last_angle2_idx + sgn * diff; + } + + /* sanity check in case of FER or BER */ + if ( idx_angle2 < 0 || idx_angle2 > ( 1 << ISM_ELEVATION_NBITS ) - 1 ) + { + idx_angle2 = angle->last_angle2_idx; + } + + /*----------------------------------------------------------------* + * Final updates + *----------------------------------------------------------------*/ + + angle->last_angle1_idx = idx_angle1; + angle->last_angle2_idx = idx_angle2; + + return; +} + +#else static void decode_angle_indices( DEC_CORE_HANDLE st0, /* i/o: bitstream handle */ @@ -748,6 +1002,8 @@ static void decode_angle_indices( return; } +#endif + /*------------------------------------------------------------------------- * decode_radius() @@ -965,13 +1221,24 @@ void ivas_ism_metadata_sid_dec( /* update last indexes to correspond to active frames coding */ if ( nBits_azimuth > ISM_AZIMUTH_NBITS ) { +#ifdef FIX_379_ANGLE + hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS ); + hIsmMetaData->position_angle.last_angle2_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS ); +#else hIsmMetaData->angle[0].last_azimuth_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS ); hIsmMetaData->angle[0].last_elevation_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS ); +#endif } else { +#ifdef FIX_379_ANGLE + hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth ); + hIsmMetaData->position_angle.last_angle2_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation ); +#else hIsmMetaData->angle[0].last_azimuth_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth ); hIsmMetaData->angle[0].last_elevation_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation ); + +#endif } /* save for smoothing metadata evolution */ diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index ab95c31b5e249606f4eb9cbe21d65e8521281069..3bfd806bdfab445b049eeb299952a7f7cb590da9 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1252,6 +1252,11 @@ typedef struct Decoder_Struct int32_t noClipping; /* number of clipped samples */ #endif int32_t last_active_ivas_total_brate; +#ifdef FIX_379_EXT_METADATA + int16_t ism_extmeta_active; /* Extended metadata active in decoder */ + int16_t ism_extmeta_cnt; /* Change frame counter for extended metadata */ +#endif + } Decoder_Struct; /* clang-format on */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 0497a0a71306aa79412085382e7bb9c0ba8f0b55..a1410c482e1031ad3e6ed4c3480ea175ba449102 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -825,9 +825,17 @@ ivas_error IVAS_DEC_GetObjectMetadata( { metadata->azimuth = 0.f; metadata->elevation = 0.f; +#ifdef FIX_379_EXT_METADATA + metadata->radius = 1.f; + metadata->spread = 0.f; + metadata->gainFactor = 1.f; + metadata->yaw = 0.f; + metadata->pitch = 0.f; +#else metadata->radius = 0.f; metadata->spread = 0.f; metadata->gainFactor = 1.f; +#endif } else { diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index 5b45d909f1aa52086d8d176e315da6aacd4574be..d34479ad2dfe3ea691a743bc24567febbae7fd06 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -64,7 +64,11 @@ * Local function declarations *-----------------------------------------------------------------------*/ +#ifdef FIX_379_ANGLE +static void encode_angle_indices( BSTR_ENC_HANDLE hBstr, ISM_METADATA_ANGLE_HANDLE angle, const int16_t last_ism_metadata_flag, const int16_t ini_frame, const int16_t idx_angle1_abs, const int16_t idx_angle2_abs, int16_t *flag_abs_angle1, int16_t *flag_abs_angle2 ); +#else static void encode_angle_indices( BSTR_ENC_HANDLE hBstr, ISM_METADATA_ANGLE_HANDLE angle, const int16_t last_ism_metadata_flag, const int16_t ini_frame, const int16_t idx_azimuth_abs, const int16_t idx_elevation_abs, int16_t *flag_abs_azimuth, int16_t *flag_abs_elevation ); +#endif static void encode_radius( BSTR_ENC_HANDLE hBstr, int16_t *last_radius_idx, int16_t *radius_diff_cnt, const int16_t last_ism_metadata_flag, const int16_t idx_radius_abs, int16_t *flag_abs_radius ); @@ -178,9 +182,18 @@ ivas_error ivas_ism_metadata_enc( ) { int16_t i, ch, nb_bits_start = 0; +#ifdef FIX_379_ANGLE + int16_t flag_abs_azimuth[MAX_NUM_OBJECTS]; + int16_t flag_abs_elevation[MAX_NUM_OBJECTS]; + int16_t idx_angle1_abs = 0; + int16_t idx_angle2_abs = 0; + int16_t flag_abs_yaw[MAX_NUM_OBJECTS]; + int16_t flag_abs_pitch[MAX_NUM_OBJECTS]; +#else int16_t idx_azimuth_abs = 0, flag_abs_azimuth[MAX_NUM_OBJECTS]; int16_t idx_elevation_abs = 0, flag_abs_elevation[MAX_NUM_OBJECTS]; int16_t flag_abs_azimuth_orientation[MAX_NUM_OBJECTS]; +#endif int16_t idx_radius_abs = 0, flag_abs_radius[MAX_NUM_OBJECTS]; float valQ; ISM_METADATA_HANDLE hIsmMetaData; @@ -228,7 +241,12 @@ ivas_error ivas_ism_metadata_enc( set_s( nb_bits_metadata, 0, nchan_transport ); set_s( flag_abs_azimuth, 0, nchan_ism ); set_s( flag_abs_elevation, 0, nchan_ism ); +#ifdef FIX_379_ANGLE + set_s( flag_abs_yaw, 0, nchan_ism ); + set_s( flag_abs_pitch, 0, nchan_ism ); +#else set_s( flag_abs_azimuth_orientation, 0, nchan_ism ); +#endif set_s( flag_abs_radius, 0, nchan_ism ); /*----------------------------------------------------------------* @@ -333,27 +351,48 @@ ivas_error ivas_ism_metadata_enc( if ( ism_mode == ISM_MODE_DISC ) { +#ifdef FIX_379_ANGLE + idx_angle1_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); + idx_angle2_abs = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); +#else idx_azimuth_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); idx_elevation_abs = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); +#endif } else /* ISM_MODE_PARAM */ { +#ifdef FIX_379_ANGLE + idx_angle1_abs = hParamIsm->azi_index[ch]; + idx_angle2_abs = hParamIsm->ele_index[ch]; +#else idx_azimuth_abs = hParamIsm->azi_index[ch]; idx_elevation_abs = hParamIsm->ele_index[ch]; +#endif } - +#ifdef FIX_379_ANGLE + encode_angle_indices( hBstr, &( hIsmMetaData->position_angle ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_angle1_abs, idx_angle2_abs, &flag_abs_azimuth[ch], &flag_abs_elevation[ch] ); +#else encode_angle_indices( hBstr, &( hIsmMetaData->angle[0] ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_azimuth_abs, idx_elevation_abs, &flag_abs_azimuth[ch], &flag_abs_elevation[ch] ); - +#endif /*----------------------------------------------------------------* * Quantize and encode radius, yaw, and pitch *----------------------------------------------------------------*/ if ( ism_mode == ISM_MODE_DISC && ism_extended_metadata_flag ) { +#ifdef FIX_379_ANGLE + idx_angle1_abs = ism_quant_meta( hIsmMetaData->yaw, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); + idx_angle2_abs = ism_quant_meta( hIsmMetaData->pitch, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); +#else idx_azimuth_abs = ism_quant_meta( hIsmMetaData->yaw, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); idx_elevation_abs = ism_quant_meta( hIsmMetaData->pitch, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); +#endif idx_radius_abs = usquant( hIsmMetaData->radius, &valQ, ISM_RADIUS_MIN, ISM_RADIUS_DELTA, 1 << ISM_RADIUS_NBITS ); +#ifdef FIX_379_ANGLE + encode_angle_indices( hBstr, &( hIsmMetaData->orientation_angle ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_angle1_abs, idx_angle2_abs, &flag_abs_yaw[ch], &flag_abs_pitch[ch] ); +#else encode_angle_indices( hBstr, &( hIsmMetaData->angle[1] ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_azimuth_abs, idx_elevation_abs, &flag_abs_azimuth_orientation[ch], &flag_abs_elevation[ch] ); +#endif encode_radius( hBstr, &hIsmMetaData->last_radius_idx, &hIsmMetaData->radius_diff_cnt, hIsmMetaData->last_ism_metadata_flag, idx_radius_abs, &flag_abs_radius[ch] ); } @@ -422,12 +461,20 @@ ivas_error ivas_ism_metadata_enc( if ( abs_next % ISM_NUM_PARAM == 0 ) { +#ifdef FIX_379_ANGLE + hIsmMeta[ch]->position_angle.angle1_diff_cnt = abs_num - 1; +#else hIsmMeta[ch]->angle[0].azimuth_diff_cnt = abs_num - 1; +#endif } if ( abs_next % ISM_NUM_PARAM == 1 ) { +#ifdef FIX_379_ANGLE + hIsmMeta[ch]->position_angle.angle2_diff_cnt = abs_num - 1; +#else hIsmMeta[ch]->angle[0].elevation_diff_cnt = abs_num - 1; +#endif /*hIsmMeta[ch]->elevation_diff_cnt = min( hIsmMeta[ch]->elevation_diff_cnt, ISM_FEC_MAX );*/ } @@ -562,17 +609,27 @@ ivas_error ivas_ism_metadata_enc_create( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM MetaData\n" ) ); } - +#ifdef FIX_379_ANGLE + st_ivas->hIsmMetaData[ch]->position_angle.last_angle1_idx = 0; + st_ivas->hIsmMetaData[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX; + st_ivas->hIsmMetaData[ch]->position_angle.last_angle2_idx = 0; + st_ivas->hIsmMetaData[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX - 1; + st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle1_idx = 0; + st_ivas->hIsmMetaData[ch]->orientation_angle.angle1_diff_cnt = ISM_FEC_MAX - 2; + st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle2_idx = 0; + st_ivas->hIsmMetaData[ch]->orientation_angle.angle2_diff_cnt = ISM_FEC_MAX - 2; +#else st_ivas->hIsmMetaData[ch]->angle[0].last_azimuth_idx = 0; st_ivas->hIsmMetaData[ch]->angle[0].azimuth_diff_cnt = ISM_FEC_MAX; st_ivas->hIsmMetaData[ch]->angle[0].last_elevation_idx = 0; st_ivas->hIsmMetaData[ch]->angle[0].elevation_diff_cnt = ISM_FEC_MAX - 1; - st_ivas->hIsmMetaData[ch]->last_radius_idx = 0; - st_ivas->hIsmMetaData[ch]->radius_diff_cnt = ISM_FEC_MAX - 2; st_ivas->hIsmMetaData[ch]->angle[1].last_azimuth_idx = 0; st_ivas->hIsmMetaData[ch]->angle[1].azimuth_diff_cnt = ISM_FEC_MAX - 2; st_ivas->hIsmMetaData[ch]->angle[1].last_elevation_idx = 0; st_ivas->hIsmMetaData[ch]->angle[1].elevation_diff_cnt = ISM_FEC_MAX - 2; +#endif + st_ivas->hIsmMetaData[ch]->last_radius_idx = 0; + st_ivas->hIsmMetaData[ch]->radius_diff_cnt = ISM_FEC_MAX - 2; st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0; ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] ); @@ -700,6 +757,244 @@ static void encode_radius( * * Encoding of an angle *----------------------------------------------------------------*/ +#ifdef FIX_379_ANGLE +static void encode_angle_indices( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle */ + const int16_t last_ism_metadata_flag, /* i : last frame ism_metadata_flag */ + const int16_t ini_frame, /* i : initialization frames counter */ + const int16_t idx_angle1_abs, /* i : Azimuth index */ + const int16_t idx_angle2_abs, /* i : Elevation index */ + int16_t *flag_abs_angle1, /* o : Azimuth/yaw encoding mode */ + int16_t *flag_abs_angle2 /* o : Elevation/pitch encoding mode */ +) +{ + int16_t idx_angle1, nbits_diff_angle1, diff; + int16_t idx_angle2, nbits_diff_angle2; + + /*----------------------------------------------------------------* + * Azimuth/yaw index encoding + *----------------------------------------------------------------*/ + + idx_angle1 = idx_angle1_abs; + + nbits_diff_angle1 = 0; + + *flag_abs_angle1 = 0; /* differential coding by default */ + if ( angle->angle1_diff_cnt == ISM_FEC_MAX /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */ + || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */ + ) + { + *flag_abs_angle1 = 1; + } + + /* try differential coding */ + if ( *flag_abs_angle1 == 0 ) + { + diff = idx_angle1_abs - angle->last_angle1_idx; + + /* azimuth is on a circle - check for diff coding for -180° -> 180° and vice versa changes */ + if ( abs( diff ) > ( ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) - ISM_MAX_AZIMUTH_DIFF_IDX ) + { + if ( diff > 0 ) + { + diff -= ( 1 << ISM_AZIMUTH_NBITS ) - 1; + } + else + { + diff += ( 1 << ISM_AZIMUTH_NBITS ) - 1; + } + } + + if ( diff == 0 ) + { + idx_angle1 = 0; + nbits_diff_angle1 = 1; + } + else if ( ABSVAL( diff ) < ISM_MAX_AZIMUTH_DIFF_IDX ) /* when diff bits >= abs bits, prefer abs */ + { + idx_angle1 = 1 << 1; + nbits_diff_angle1 = 1; + + if ( diff < 0 ) + { + idx_angle1 += 1; /* negative sign */ + diff *= -1; + } + else + { + idx_angle1 += 0; /* positive sign */ + } + + idx_angle1 = idx_angle1 << diff; + nbits_diff_angle1++; + + /* unary coding of "diff */ + idx_angle1 += ( ( 1 << diff ) - 1 ); + nbits_diff_angle1 += diff; + + if ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 ) + { + /* add stop bit - only for codewords shorter than ISM_AZIMUTH_NBITS */ + idx_angle1 = idx_angle1 << 1; + nbits_diff_angle1++; + } + } + else + { + *flag_abs_angle1 = 1; + } + } + + /* update counter */ + if ( *flag_abs_angle1 == 0 ) + { + angle->angle1_diff_cnt++; + angle->angle2_diff_cnt = min( angle->angle2_diff_cnt, ISM_FEC_MAX ); + } + else + { + angle->angle1_diff_cnt = 0; + } + + /* Write azimuth/yaw */ + push_indice( hBstr, IND_ISM_AZIMUTH_DIFF_FLAG, *flag_abs_angle1, 1 ); + + if ( *flag_abs_angle1 ) + { + push_indice( hBstr, IND_ISM_AZIMUTH, idx_angle1, ISM_AZIMUTH_NBITS ); + } + else + { + push_indice( hBstr, IND_ISM_AZIMUTH, idx_angle1, nbits_diff_angle1 ); + } + + /*----------------------------------------------------------------* + * Elevation/pitch index encoding + *----------------------------------------------------------------*/ + + idx_angle2 = idx_angle2_abs; + nbits_diff_angle2 = 0; + *flag_abs_angle2 = 0; /* differential coding by default */ + if ( angle->angle2_diff_cnt == ISM_FEC_MAX /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */ + || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */ + ) + { + *flag_abs_angle2 = 1; + } + + /* note: elevation/pitch is coded starting from the second frame only (it is meaningless in the init_frame) */ + if ( ini_frame == 0 ) + { + *flag_abs_angle2 = 1; + angle->last_angle2_idx = idx_angle2_abs; + } + + diff = idx_angle2_abs - angle->last_angle2_idx; + + /* avoid absolute coding of elevation/pitch if absolute coding was already used for azimuth/yaw */ + if ( *flag_abs_angle1 == 1 ) + { + int16_t diff_orig = diff; + + *flag_abs_angle2 = 0; + + + if ( diff >= 0 ) + { + diff = min( diff, ISM_MAX_ELEVATION_DIFF_IDX ); + } + else + { + diff = -1 * min( -diff, ISM_MAX_ELEVATION_DIFF_IDX ); + } + + if ( last_ism_metadata_flag == 0 || abs( diff_orig - diff ) > ISM_MAX_ELEVATION_DIFF_IDX ) + { + angle->angle2_diff_cnt = ISM_FEC_MAX - 1; + } + } + + /* try differential coding */ + if ( *flag_abs_angle2 == 0 ) + { + if ( diff == 0 ) + { + idx_angle2 = 0; + nbits_diff_angle2 = 1; + } + else if ( ABSVAL( diff ) <= ISM_MAX_ELEVATION_DIFF_IDX ) + { + idx_angle2 = 1 << 1; + nbits_diff_angle2 = 1; + + if ( diff < 0 ) + { + idx_angle2 += 1; /* negative sign */ + diff *= -1; + } + else + { + idx_angle2 += 0; /* positive sign */ + } + + idx_angle2 = idx_angle2 << diff; + nbits_diff_angle2++; + + /* unary coding of "diff */ + idx_angle2 += ( ( 1 << diff ) - 1 ); + nbits_diff_angle2 += diff; + + if ( nbits_diff_angle2 < ISM_ELEVATION_NBITS ) + { + /* add stop bit */ + idx_angle2 = idx_angle2 << 1; + nbits_diff_angle2++; + } + } + else + { + *flag_abs_angle2 = 1; + } + } + + /* update counter */ + if ( *flag_abs_angle2 == 0 ) + { + angle->angle2_diff_cnt++; + angle->angle2_diff_cnt = min( angle->angle2_diff_cnt, ISM_FEC_MAX ); + } + else + { + angle->angle2_diff_cnt = 0; + } + + /* Write elevation */ + if ( *flag_abs_angle1 == 0 ) /* do not write "flag_abs_elevation/pitch" if "flag_abs_azimuth/yaw == 1" */ + { + push_indice( hBstr, IND_ISM_ELEVATION_DIFF_FLAG, *flag_abs_angle2, 1 ); + } + + if ( *flag_abs_angle2 ) + { + push_indice( hBstr, IND_ISM_ELEVATION, idx_angle2, ISM_ELEVATION_NBITS ); + } + else + { + push_indice( hBstr, IND_ISM_ELEVATION, idx_angle2, nbits_diff_angle2 ); + } + + /*----------------------------------------------------------------* + * Updates + *----------------------------------------------------------------*/ + + angle->last_angle1_idx = idx_angle1_abs; + angle->last_angle2_idx = idx_angle2_abs; + + return; +} + +#else static void encode_angle_indices( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ @@ -936,7 +1231,7 @@ static void encode_angle_indices( return; } - +#endif #ifdef DISCRETE_ISM_DTX_CNG /*-------------------------------------------------------------------* @@ -1056,13 +1351,24 @@ void ivas_ism_metadata_sid_enc( /* update last indexes to correspond to active frames coding */ if ( nBits_azimuth > ISM_AZIMUTH_NBITS ) { +#ifdef FIX_379_ANGLE + hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS ); + hIsmMetaData->position_angle.last_angle2_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS ); + +#else hIsmMetaData->angle[0].last_azimuth_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS ); hIsmMetaData->angle[0].last_elevation_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS ); +#endif } else { +#ifdef FIX_379_ANGLE + hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth ); + hIsmMetaData->position_angle.last_angle2_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation ); +#else hIsmMetaData->angle[0].last_azimuth_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth ); hIsmMetaData->angle[0].last_elevation_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation ); +#endif } } } diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index ebc2551ce2ce9896c7d4d559bf0ff291676bdc4b..d9bd9d688fffc61b8b26c9595a0719e53bbcafa6 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -61,6 +61,9 @@ struct IVAS_ENC bool ismMetadataProvided[MAX_NUM_OBJECTS]; bool maxBandwidthUser; /* Was a specific max bandwith selected by the user? */ IVAS_ENC_BANDWIDTH newBandwidthApi; /* maximum encoded bandwidth, as set on API level */ +#ifdef FIX_379_EXT_METADATA + bool extMetadataApi; /* External metadata requested, to be checked against current bit rate */ +#endif }; /*---------------------------------------------------------------------* @@ -75,7 +78,11 @@ static int16_t getInputBufferSize( const Encoder_Struct *st_ivas ); static ivas_error doCommonConfigureChecks( IVAS_ENC_HANDLE hIvasEnc ); static ivas_error doCommonSetterChecks( IVAS_ENC_HANDLE hIvasEnc ); static ivas_error sanitizeBandwidth( const IVAS_ENC_HANDLE hIvasEnc ); +#ifdef FIX_379_EXT_METADATA +static ivas_error sanitizeBitrateISM( const ENCODER_CONFIG_HANDLE hEncoderConfig, const IVAS_ENC_HANDLE hIvasEnc ); +#else static ivas_error sanitizeBitrateISM( const ENCODER_CONFIG_HANDLE hEncoderConfig ); +#endif static void init_encoder_config( ENCODER_CONFIG_HANDLE hEncoderConfig ); static void resetIsmMetadataProvidedFlags( IVAS_ENC_HANDLE hIvasEnc ); static ivas_error bandwidthApiToInternal( const IVAS_ENC_BANDWIDTH maxBandwidth, int16_t *internalMaxBandwidth ); @@ -391,6 +398,9 @@ ivas_error IVAS_ENC_ConfigureForObjects( st_ivas->hEncoderConfig->nchan_ism = numObjects; #endif st_ivas->hEncoderConfig->ism_extended_metadata_flag = ism_extended_metadata; +#ifdef FIX_379_EXT_METADATA + hIvasEnc->extMetadataApi = ( ism_extended_metadata == 1 ); +#endif hIvasEnc->maxBandwidthUser = max_bwidth_user; error = configureEncoder( hIvasEnc, inputFs, bitrate, maxBandwidth, dtxConfig, IVAS_ENC_GetDefaultChannelAwareConfig() ); @@ -781,7 +791,11 @@ static ivas_error configureEncoder( } else if ( hEncoderConfig->ivas_format == ISM_FORMAT ) { +#ifdef FIX_379_EXT_METADATA + if ( ( error = sanitizeBitrateISM( hEncoderConfig, hIvasEnc ) ) != IVAS_ERR_OK ) +#else if ( ( error = sanitizeBitrateISM( hEncoderConfig ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1737,7 +1751,11 @@ static ivas_error setBitrate( if ( hEncoderConfig->ivas_format == ISM_FORMAT ) { +#ifdef FIX_379_EXT_METADATA + if ( ( error = sanitizeBitrateISM( hEncoderConfig, hIvasEnc ) ) != IVAS_ERR_OK ) +#else if ( ( error = sanitizeBitrateISM( hEncoderConfig ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1976,7 +1994,12 @@ static ivas_error sanitizeBandwidth( *---------------------------------------------------------------------*/ static ivas_error sanitizeBitrateISM( +#ifdef FIX_379_EXT_METADATA + const ENCODER_CONFIG_HANDLE hEncoderConfig, + const IVAS_ENC_HANDLE hIvasEnc ) +#else const ENCODER_CONFIG_HANDLE hEncoderConfig ) +#endif { if ( hEncoderConfig->ivas_total_brate > IVAS_128k && hEncoderConfig->nchan_inp == 1 ) { @@ -2008,10 +2031,21 @@ static ivas_error sanitizeBitrateISM( return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too low bitrate for 4 ISM specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); } +#ifdef FIX_379_EXT_METADATA + if ( hIvasEnc->extMetadataApi ) + { + hEncoderConfig->ism_extended_metadata_flag = ( hEncoderConfig->ivas_total_brate >= ISM_EXTENDED_METADATA_BRATE ); + } + else + { + hEncoderConfig->ism_extended_metadata_flag = 0; + } +#else if ( hEncoderConfig->ivas_total_brate < ISM_EXTENDED_METADATA_BRATE && hEncoderConfig->ism_extended_metadata_flag == 1 ) { return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too low bitrate for extended metadata format specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); } +#endif return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index 4449945711a1d7cc20fd6e5b929628a2fb3c301f..b14db0b7c2f69c0d784f3f528c4dfa4bc7e8cabe 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -96,7 +96,7 @@ ivas_error TDREND_MIX_SRC_SetPos( /*-------------------------------------------------------------------* * TDREND_MIX_SRC_SetDir() * - * Set source direciton + * Set source direction --------------------------------------------------------------------*/ ivas_error TDREND_MIX_SRC_SetDir( @@ -460,7 +460,11 @@ static void TDREND_SRC_SPATIAL_Init( SrcSpatial_p->DistAttenEnabled = FALSE; SrcSpatial_p->DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; SrcSpatial_p->DistAtten.RefDist = 1.0f; +#ifdef FIX_379_EXT_METADATA + SrcSpatial_p->DistAtten.MaxDist = 15.75f; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 */ +#else SrcSpatial_p->DistAtten.MaxDist = 10.0f; +#endif SrcSpatial_p->DistAtten.RollOffFactor = 1.0f; return; diff --git a/lib_util/ism_file_reader.c b/lib_util/ism_file_reader.c index b27d0e9e78d5ad243cefc98c67bbc64b6c22b06b..0aeca6d6a06e36cdf8df76f6971670d356fb0923 100644 --- a/lib_util/ism_file_reader.c +++ b/lib_util/ism_file_reader.c @@ -135,12 +135,21 @@ ivas_error IsmFileReader_readNextFrame( meta_prm[i++] = (float) atof( char_ptr ); } +#ifdef FIX_379_EXT_METADATA + /* Verify the number of metadata values. */ + if ( i < NUM_MIN_ISM_METADATA || char_ptr != NULL ) + { + /* Invalid number of metadata parameters (2-7 supported) */ + return IVAS_ERR_ISM_FILE_READER_INVALID_METADATA_FORMAT; + } +#else /* Check if minimum number of metadata values were read. Additional values are ignored. */ if ( i < NUM_MIN_ISM_METADATA ) { /* Not enough values provided in one line */ return IVAS_ERR_ISM_FILE_READER_INVALID_METADATA_FORMAT; } +#endif ismMetadata->azimuth = meta_prm[0]; @@ -162,7 +171,11 @@ ivas_error IsmFileReader_readNextFrame( return IVAS_ERR_ISM_INVALID_METADATA_VALUE; } +#ifdef FIX_379_EXT_METADATA + if ( ismMetadata->radius < 0 ) /* Negative radius not supported. Max quantized radius = (2^ISM_RADIUS_NBITS-1)*0.25 = 15.75 */ +#else if ( ismMetadata->radius < 0 ) // Ivas_fmToDo: to be reviewed +#endif { return IVAS_ERR_ISM_INVALID_METADATA_VALUE; }