From d92c60dc03c8222295c3baa2ff8165b5695856fc Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 3 Sep 2021 11:18:27 -0400 Subject: [PATCH] multi_audio: Rework validity checks in the constructor. In hrev55048, checks were added to bail on initialization if invalid audio formats were present either in inputs or outputs, which broke any audio nodes that supported only one or the other. Now, instead, we check channels first, and even then do not bail on invalid formats, but simply do not declare support for inputs or outputs respectively. This solves the initial cause of #17235. However, that ticket refers to an unrelated problem this bug merely exposed, and so it should remain open until that is resolved. --- .../multi_audio/MultiAudioNode.cpp | 91 +++++++++---------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.cpp b/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.cpp index bccf754a2a..2a2511cf01 100644 --- a/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.cpp +++ b/src/add-ons/media/media-add-ons/multi_audio/MultiAudioNode.cpp @@ -193,60 +193,59 @@ MultiAudioNode::MultiAudioNode(BMediaAddOn* addon, const char* name, fAddOn = addon; fId = internalID; - AddNodeKind(B_PHYSICAL_OUTPUT); - AddNodeKind(B_PHYSICAL_INPUT); + if (fDevice->Description().output_channel_count > 0) { + // initialize our preferred format objects + fOutputPreferredFormat.type = B_MEDIA_RAW_AUDIO; + fOutputPreferredFormat.u.raw_audio.format + = MultiAudio::convert_to_media_format( + fDevice->FormatInfo().output.format); + fOutputPreferredFormat.u.raw_audio.valid_bits + = MultiAudio::convert_to_valid_bits( + fDevice->FormatInfo().output.format); + fOutputPreferredFormat.u.raw_audio.channel_count = 2; + fOutputPreferredFormat.u.raw_audio.frame_rate + = MultiAudio::convert_to_sample_rate(fDevice->FormatInfo().output.rate); + // measured in Hertz + fOutputPreferredFormat.u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN; - // initialize our preferred format objects - fOutputPreferredFormat.type = B_MEDIA_RAW_AUDIO; - fOutputPreferredFormat.u.raw_audio.format - = MultiAudio::convert_to_media_format( - fDevice->FormatInfo().output.format); - fOutputPreferredFormat.u.raw_audio.valid_bits - = MultiAudio::convert_to_valid_bits( - fDevice->FormatInfo().output.format); - fOutputPreferredFormat.u.raw_audio.channel_count = 2; - fOutputPreferredFormat.u.raw_audio.frame_rate - = MultiAudio::convert_to_sample_rate(fDevice->FormatInfo().output.rate); - // measured in Hertz - fOutputPreferredFormat.u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN; + if (fOutputPreferredFormat.u.raw_audio.format != 0) { + AddNodeKind(B_PHYSICAL_OUTPUT); - if (fOutputPreferredFormat.u.raw_audio.format == 0) { - fInitStatus = B_BAD_VALUE; - return; + // we'll use the consumer's preferred buffer size, if any + fOutputPreferredFormat.u.raw_audio.buffer_size + = fDevice->BufferList().return_playback_buffer_size + * (fOutputPreferredFormat.u.raw_audio.format + & media_raw_audio_format::B_AUDIO_SIZE_MASK) + * fOutputPreferredFormat.u.raw_audio.channel_count; + } } - // we'll use the consumer's preferred buffer size, if any - fOutputPreferredFormat.u.raw_audio.buffer_size - = fDevice->BufferList().return_playback_buffer_size - * (fOutputPreferredFormat.u.raw_audio.format - & media_raw_audio_format::B_AUDIO_SIZE_MASK) - * fOutputPreferredFormat.u.raw_audio.channel_count; + if (fDevice->Description().input_channel_count > 0) { + // initialize our preferred format objects + fInputPreferredFormat.type = B_MEDIA_RAW_AUDIO; + fInputPreferredFormat.u.raw_audio.format + = MultiAudio::convert_to_media_format( + fDevice->FormatInfo().input.format); + fInputPreferredFormat.u.raw_audio.valid_bits + = MultiAudio::convert_to_valid_bits(fDevice->FormatInfo().input.format); + fInputPreferredFormat.u.raw_audio.channel_count = 2; + fInputPreferredFormat.u.raw_audio.frame_rate + = MultiAudio::convert_to_sample_rate(fDevice->FormatInfo().input.rate); + // measured in Hertz + fInputPreferredFormat.u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN; - // initialize our preferred format objects - fInputPreferredFormat.type = B_MEDIA_RAW_AUDIO; - fInputPreferredFormat.u.raw_audio.format - = MultiAudio::convert_to_media_format( - fDevice->FormatInfo().input.format); - fInputPreferredFormat.u.raw_audio.valid_bits - = MultiAudio::convert_to_valid_bits(fDevice->FormatInfo().input.format); - fInputPreferredFormat.u.raw_audio.channel_count = 2; - fInputPreferredFormat.u.raw_audio.frame_rate - = MultiAudio::convert_to_sample_rate(fDevice->FormatInfo().input.rate); - // measured in Hertz - fInputPreferredFormat.u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN; + if (fInputPreferredFormat.u.raw_audio.format != 0) { + AddNodeKind(B_PHYSICAL_INPUT); - if (fInputPreferredFormat.u.raw_audio.format == 0) { - fInitStatus = B_BAD_VALUE; - return; + // we'll use the consumer's preferred buffer size, if any + fInputPreferredFormat.u.raw_audio.buffer_size + = fDevice->BufferList().return_record_buffer_size + * (fInputPreferredFormat.u.raw_audio.format + & media_raw_audio_format::B_AUDIO_SIZE_MASK) + * fInputPreferredFormat.u.raw_audio.channel_count; + } } - // we'll use the consumer's preferred buffer size, if any - fInputPreferredFormat.u.raw_audio.buffer_size - = fDevice->BufferList().return_record_buffer_size - * (fInputPreferredFormat.u.raw_audio.format - & media_raw_audio_format::B_AUDIO_SIZE_MASK) - * fInputPreferredFormat.u.raw_audio.channel_count; - if (config != NULL) { fConfig = *config; PRINT_OBJECT(*config);