@@ -48,59 +48,97 @@ extern void iamf_mix_stream_log(int chs, float *out, int size);
4848extern void iamf_stream_log_free ();
4949#endif
5050
51- // Helper function to check if audio element has binaural layout
52- static int _audio_element_binaural_layout_check (obu_sub_mix_t * sub_mix ,
53- iamf_database_t * database ) {
54- int n = array_size (sub_mix -> audio_element_configs );
55-
56- for (int i = 0 ; i < n ; i ++ ) {
57- obu_audio_element_config_t * aec = def_value_wrap_optional_ptr (
58- array_at (sub_mix -> audio_element_configs , i ));
59- iamf_audio_element_obu_t * e =
60- iamf_database_get_audio_element_obu (database , aec -> element_id );
61-
62- if (e && e -> audio_element_type == ck_audio_element_type_channel_based ) {
63- channel_based_audio_element_obu_t * cae =
64- def_channel_based_audio_element_obu_ptr (e );
65- if (array_size (cae -> channel_audio_layer_configs ) == 1 ) {
66- obu_channel_layer_config_t * clc = def_value_wrap_optional_ptr (
67- array_at (cae -> channel_audio_layer_configs , 0 ));
68- if (clc -> loudspeaker_layout == ck_iamf_loudspeaker_layout_binaural )
69- return def_true ;
70- }
51+ static int _matching_loudess_layout_check (iamf_mix_presentation_obu_t * mpo ,
52+ iamf_layout_t target_layout ,
53+ void * data ) {
54+ int m = array_size (mpo -> sub_mixes );
55+ for (int j = 0 ; j < m ; ++ j ) {
56+ obu_sub_mix_t * sub =
57+ def_value_wrap_optional_ptr (array_at (mpo -> sub_mixes , j ));
58+ int n = array_size (sub -> loudness_layouts );
59+
60+ for (int i = 0 ; i < n ; ++ i ) {
61+ iamf_layout_t * check_layout =
62+ def_value_wrap_optional_ptr (array_at (sub -> loudness_layouts , i ));
63+ if (!check_layout ) continue ;
64+ if (iamf_layout_is_equal (target_layout , * check_layout )) return def_true ;
7165 }
7266 }
67+
7368 return def_false ;
7469}
7570
76- static int _matching_loudess_layout_check (obu_sub_mix_t * sub ,
77- iamf_layout_t target_layout ,
78- void * data ) {
79- int n = array_size (sub -> loudness_layouts );
80-
81- for (int i = 0 ; i < n ; ++ i ) {
82- iamf_layout_t * check_layout =
83- def_value_wrap_optional_ptr (array_at (sub -> loudness_layouts , i ));
84- if (!check_layout ) continue ;
85- if (iamf_layout_is_equal (target_layout , * check_layout )) return def_true ;
71+ static int _stereo_layout_and_headphones_check_internal (
72+ iamf_mix_presentation_obu_t * mpo , void * data , int headphones ) {
73+ iamf_database_t * database = (iamf_database_t * )data ;
74+ if (array_size (mpo -> sub_mixes ) != 1 ) return def_false ;
75+
76+ obu_sub_mix_t * sub_mix =
77+ def_value_wrap_optional_ptr (array_at (mpo -> sub_mixes , 0 ));
78+
79+ if (array_size (sub_mix -> audio_element_configs ) != 1 ||
80+ array_size (sub_mix -> loudness_layouts ) != 1 ||
81+ !_matching_loudess_layout_check (
82+ mpo , def_sound_system_layout_instance (SOUND_SYSTEM_A ), data ))
83+ return def_false ;
84+
85+ obu_audio_element_config_t * aec =
86+ def_value_wrap_optional_ptr (array_at (sub_mix -> audio_element_configs , 0 ));
87+ iamf_audio_element_obu_t * e =
88+ iamf_database_get_audio_element_obu (database , aec -> element_id );
89+
90+ if (e && e -> audio_element_type == ck_audio_element_type_channel_based ) {
91+ channel_based_audio_element_obu_t * cae =
92+ def_channel_based_audio_element_obu_ptr (e );
93+ if (array_size (cae -> channel_audio_layer_configs ) == 1 ) {
94+ obu_channel_layer_config_t * clc = def_value_wrap_optional_ptr (
95+ array_at (cae -> channel_audio_layer_configs , 0 ));
96+ if (clc -> loudspeaker_layout == ck_iamf_loudspeaker_layout_stereo &&
97+ (!headphones || !aec -> rendering_config .headphones_rendering_mode ))
98+ return def_true ;
99+ }
86100 }
87-
88101 return def_false ;
89102}
90103
91- static int _stereo_layout_check (obu_sub_mix_t * sub , iamf_layout_t unused ,
92- void * data ) {
93- return _matching_loudess_layout_check (
94- sub , def_sound_system_layout_instance (SOUND_SYSTEM_A ), data ) &&
95- (array_size (sub -> loudness_layouts ) == 1 );
104+ static int _stereo_layout_and_headphones_check (iamf_mix_presentation_obu_t * mpo ,
105+ iamf_layout_t unused ,
106+ void * data ) {
107+ return _stereo_layout_and_headphones_check_internal (mpo , data , 1 );
108+ }
109+
110+ static int _stereo_layout_check (iamf_mix_presentation_obu_t * mpo ,
111+ iamf_layout_t unused , void * data ) {
112+ return _stereo_layout_and_headphones_check_internal (mpo , data , 0 );
96113}
97114
98- static int _binaural_layout_check (obu_sub_mix_t * sub ,
99- iamf_layout_t target_layout , void * data ) {
115+ static int _binaural_layout_check (iamf_mix_presentation_obu_t * mpo ,
116+ iamf_layout_t unused , void * data ) {
100117 iamf_database_t * database = (iamf_database_t * )data ;
101- return target_layout .type == ck_iamf_layout_type_binaural
102- ? _audio_element_binaural_layout_check (sub , database )
103- : def_false ;
118+ if (array_size (mpo -> sub_mixes ) != 1 ) return def_false ;
119+
120+ obu_sub_mix_t * sub_mix =
121+ def_value_wrap_optional_ptr (array_at (mpo -> sub_mixes , 0 ));
122+
123+ if (array_size (sub_mix -> audio_element_configs ) != 1 ) return def_false ;
124+
125+ obu_audio_element_config_t * aec =
126+ def_value_wrap_optional_ptr (array_at (sub_mix -> audio_element_configs , 0 ));
127+ iamf_audio_element_obu_t * e =
128+ iamf_database_get_audio_element_obu (database , aec -> element_id );
129+
130+ if (e && e -> audio_element_type == ck_audio_element_type_channel_based ) {
131+ channel_based_audio_element_obu_t * cae =
132+ def_channel_based_audio_element_obu_ptr (e );
133+ if (array_size (cae -> channel_audio_layer_configs ) == 1 ) {
134+ obu_channel_layer_config_t * clc = def_value_wrap_optional_ptr (
135+ array_at (cae -> channel_audio_layer_configs , 0 ));
136+ if (clc -> loudspeaker_layout == ck_iamf_loudspeaker_layout_binaural )
137+ return def_true ;
138+ }
139+ }
140+
141+ return def_false ;
104142}
105143
106144static sample_format_t _get_sample_format (uint32_t bit_depth , int interleaved ) {
@@ -319,6 +357,10 @@ static iamf_mix_presentation_obu_t *iamf_decoder_priv_get_best_mix_presentation(
319357 } else if (ctx -> layout .type ==
320358 ck_iamf_layout_type_loudspeakers_ss_convention ) {
321359 if (ctx -> layout .sound_system == SOUND_SYSTEM_A ) {
360+ obu = iamf_database_find_mix_presentation_obu (
361+ database , _stereo_layout_and_headphones_check , target_layout );
362+ if (obu ) return obu ;
363+
322364 obu = iamf_database_find_mix_presentation_obu (
323365 database , _stereo_layout_check , target_layout );
324366 if (obu ) return obu ;
0 commit comments