Loading system/btif/include/btif_a2dp_sink.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -109,6 +109,9 @@ void btif_a2dp_sink_on_stopped(tBTA_AV_SUSPEND* p_av_suspend); // |tBTA_AV_SUSPEND|. // |tBTA_AV_SUSPEND|. void btif_a2dp_sink_on_suspended(tBTA_AV_SUSPEND* p_av_suspend); void btif_a2dp_sink_on_suspended(tBTA_AV_SUSPEND* p_av_suspend); // Start the decoder for the A2DP Sink module. bool btif_a2dp_sink_on_start(void); // Enable/disable discarding of received A2DP frames. // Enable/disable discarding of received A2DP frames. // If |enable| is true, the discarding is enabled, otherwise is disabled. // If |enable| is true, the discarding is enabled, otherwise is disabled. void btif_a2dp_sink_set_rx_flush(bool enable); void btif_a2dp_sink_set_rx_flush(bool enable); Loading system/btif/src/btif_a2dp_sink.cc +65 −1 Original line number Original line Diff line number Diff line Loading @@ -64,7 +64,9 @@ enum { BTIF_MEDIA_SINK_DECODER_UPDATE = 1, BTIF_MEDIA_SINK_DECODER_UPDATE = 1, BTIF_MEDIA_SINK_CLEAR_TRACK, BTIF_MEDIA_SINK_CLEAR_TRACK, BTIF_MEDIA_SINK_SET_FOCUS_STATE, BTIF_MEDIA_SINK_SET_FOCUS_STATE, BTIF_MEDIA_SINK_AUDIO_RX_FLUSH BTIF_MEDIA_SINK_AUDIO_RX_FLUSH, BTIF_MEDIA_SINK_START, BTIF_MEDIA_SINK_SUSPEND }; }; typedef struct { typedef struct { Loading Loading @@ -149,6 +151,8 @@ static void btif_a2dp_sink_set_focus_state_event( btif_a2dp_sink_focus_state_t state); btif_a2dp_sink_focus_state_t state); static void btif_a2dp_sink_audio_rx_flush_event(); static void btif_a2dp_sink_audio_rx_flush_event(); static void btif_a2dp_sink_clear_track_event_req(); static void btif_a2dp_sink_clear_track_event_req(); static void btif_a2dp_sink_on_start_event(); static void btif_a2dp_sink_on_suspend_event(); UNUSED_ATTR static const char* dump_media_event(uint16_t event) { UNUSED_ATTR static const char* dump_media_event(uint16_t event) { switch (event) { switch (event) { Loading @@ -156,6 +160,8 @@ UNUSED_ATTR static const char* dump_media_event(uint16_t event) { CASE_RETURN_STR(BTIF_MEDIA_SINK_CLEAR_TRACK) CASE_RETURN_STR(BTIF_MEDIA_SINK_CLEAR_TRACK) CASE_RETURN_STR(BTIF_MEDIA_SINK_SET_FOCUS_STATE) CASE_RETURN_STR(BTIF_MEDIA_SINK_SET_FOCUS_STATE) CASE_RETURN_STR(BTIF_MEDIA_SINK_AUDIO_RX_FLUSH) CASE_RETURN_STR(BTIF_MEDIA_SINK_AUDIO_RX_FLUSH) CASE_RETURN_STR(BTIF_MEDIA_SINK_START) CASE_RETURN_STR(BTIF_MEDIA_SINK_SUSPEND) default: default: break; break; } } Loading Loading @@ -364,6 +370,12 @@ static void btif_a2dp_sink_command_ready(BT_HDR* p_msg) { case BTIF_MEDIA_SINK_AUDIO_RX_FLUSH: case BTIF_MEDIA_SINK_AUDIO_RX_FLUSH: btif_a2dp_sink_audio_rx_flush_event(); btif_a2dp_sink_audio_rx_flush_event(); break; break; case BTIF_MEDIA_SINK_START: btif_a2dp_sink_on_start_event(); break; case BTIF_MEDIA_SINK_SUSPEND: btif_a2dp_sink_on_suspend_event(); break; default: default: LOG_ERROR(LOG_TAG, "%s: unknown event %d", __func__, p_msg->event); LOG_ERROR(LOG_TAG, "%s: unknown event %d", __func__, p_msg->event); break; break; Loading Loading @@ -392,6 +404,11 @@ void btif_a2dp_sink_update_decoder(const uint8_t* p_codec_info) { void btif_a2dp_sink_on_idle() { void btif_a2dp_sink_on_idle() { LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__); BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR))); p_buf->event = BTIF_MEDIA_SINK_SUSPEND; btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; btif_a2dp_sink_audio_handle_stop_decoding(); btif_a2dp_sink_audio_handle_stop_decoding(); btif_a2dp_sink_clear_track_event_req(); btif_a2dp_sink_clear_track_event_req(); Loading @@ -399,16 +416,37 @@ void btif_a2dp_sink_on_idle() { void btif_a2dp_sink_on_stopped(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { void btif_a2dp_sink_on_stopped(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__); BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR))); p_buf->event = BTIF_MEDIA_SINK_SUSPEND; btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; btif_a2dp_sink_audio_handle_stop_decoding(); btif_a2dp_sink_audio_handle_stop_decoding(); } } void btif_a2dp_sink_on_suspended(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { void btif_a2dp_sink_on_suspended(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__); BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR))); p_buf->event = BTIF_MEDIA_SINK_SUSPEND; btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; btif_a2dp_sink_audio_handle_stop_decoding(); btif_a2dp_sink_audio_handle_stop_decoding(); } } bool btif_a2dp_sink_on_start() { LOG_INFO(LOG_TAG, "%s", __func__); BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR))); p_buf->event = BTIF_MEDIA_SINK_START; btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); return true; } static void btif_a2dp_sink_audio_handle_stop_decoding() { static void btif_a2dp_sink_audio_handle_stop_decoding() { LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__); alarm_t* old_alarm; alarm_t* old_alarm; Loading Loading @@ -592,6 +630,10 @@ static void btif_a2dp_sink_decoder_update_event( return; return; } } if (btif_a2dp_sink_cb.decoder_interface->decoder_configure != nullptr) { btif_a2dp_sink_cb.decoder_interface->decoder_configure(p_buf->codec_info); } APPL_TRACE_DEBUG("%s: create audio track", __func__); APPL_TRACE_DEBUG("%s: create audio track", __func__); btif_a2dp_sink_cb.audio_track = btif_a2dp_sink_cb.audio_track = #ifndef OS_GENERIC #ifndef OS_GENERIC Loading Loading @@ -694,3 +736,25 @@ static void btif_a2dp_sink_clear_track_event_req() { btif_a2dp_sink_cb.worker_thread.DoInThread( btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); } } static void btif_a2dp_sink_on_start_event() { LOG_INFO(LOG_TAG, "%s", __func__); if ((btif_a2dp_sink_cb.decoder_interface != nullptr) && (btif_a2dp_sink_cb.decoder_interface->decoder_start != nullptr)) { btif_a2dp_sink_cb.decoder_interface->decoder_start(); } return; } static void btif_a2dp_sink_on_suspend_event() { LOG_INFO(LOG_TAG, "%s", __func__); if ((btif_a2dp_sink_cb.decoder_interface != nullptr) && (btif_a2dp_sink_cb.decoder_interface->decoder_suspend != nullptr)) { btif_a2dp_sink_cb.decoder_interface->decoder_suspend(); } return; } system/btif/src/btif_av.cc +1 −0 Original line number Original line Diff line number Diff line Loading @@ -1869,6 +1869,7 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event, if (peer_.IsSource() && peer_.IsActivePeer()) { if (peer_.IsSource() && peer_.IsActivePeer()) { // Remove flush state, ready for streaming // Remove flush state, ready for streaming btif_a2dp_sink_set_rx_flush(false); btif_a2dp_sink_set_rx_flush(false); btif_a2dp_sink_on_start(); } } if (should_suspend) { if (should_suspend) { Loading system/stack/a2dp/a2dp_aac.cc +5 −1 Original line number Original line Diff line number Diff line Loading @@ -102,8 +102,12 @@ static const tA2DP_ENCODER_INTERFACE a2dp_encoder_interface_aac = { }; }; static const tA2DP_DECODER_INTERFACE a2dp_decoder_interface_aac = { static const tA2DP_DECODER_INTERFACE a2dp_decoder_interface_aac = { a2dp_aac_decoder_init, a2dp_aac_decoder_cleanup, a2dp_aac_decoder_init, a2dp_aac_decoder_cleanup, a2dp_aac_decoder_decode_packet, a2dp_aac_decoder_decode_packet, nullptr, // decoder_start nullptr, // decoder_suspend nullptr, // decoder_configure }; }; UNUSED_ATTR static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAac( UNUSED_ATTR static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAac( Loading system/stack/a2dp/a2dp_sbc.cc +5 −1 Original line number Original line Diff line number Diff line Loading @@ -103,8 +103,12 @@ static const tA2DP_ENCODER_INTERFACE a2dp_encoder_interface_sbc = { }; }; static const tA2DP_DECODER_INTERFACE a2dp_decoder_interface_sbc = { static const tA2DP_DECODER_INTERFACE a2dp_decoder_interface_sbc = { a2dp_sbc_decoder_init, a2dp_sbc_decoder_cleanup, a2dp_sbc_decoder_init, a2dp_sbc_decoder_cleanup, a2dp_sbc_decoder_decode_packet, a2dp_sbc_decoder_decode_packet, nullptr, // decoder_start nullptr, // decoder_suspend nullptr, // decoder_configure }; }; static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilitySbc( static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilitySbc( Loading Loading
system/btif/include/btif_a2dp_sink.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -109,6 +109,9 @@ void btif_a2dp_sink_on_stopped(tBTA_AV_SUSPEND* p_av_suspend); // |tBTA_AV_SUSPEND|. // |tBTA_AV_SUSPEND|. void btif_a2dp_sink_on_suspended(tBTA_AV_SUSPEND* p_av_suspend); void btif_a2dp_sink_on_suspended(tBTA_AV_SUSPEND* p_av_suspend); // Start the decoder for the A2DP Sink module. bool btif_a2dp_sink_on_start(void); // Enable/disable discarding of received A2DP frames. // Enable/disable discarding of received A2DP frames. // If |enable| is true, the discarding is enabled, otherwise is disabled. // If |enable| is true, the discarding is enabled, otherwise is disabled. void btif_a2dp_sink_set_rx_flush(bool enable); void btif_a2dp_sink_set_rx_flush(bool enable); Loading
system/btif/src/btif_a2dp_sink.cc +65 −1 Original line number Original line Diff line number Diff line Loading @@ -64,7 +64,9 @@ enum { BTIF_MEDIA_SINK_DECODER_UPDATE = 1, BTIF_MEDIA_SINK_DECODER_UPDATE = 1, BTIF_MEDIA_SINK_CLEAR_TRACK, BTIF_MEDIA_SINK_CLEAR_TRACK, BTIF_MEDIA_SINK_SET_FOCUS_STATE, BTIF_MEDIA_SINK_SET_FOCUS_STATE, BTIF_MEDIA_SINK_AUDIO_RX_FLUSH BTIF_MEDIA_SINK_AUDIO_RX_FLUSH, BTIF_MEDIA_SINK_START, BTIF_MEDIA_SINK_SUSPEND }; }; typedef struct { typedef struct { Loading Loading @@ -149,6 +151,8 @@ static void btif_a2dp_sink_set_focus_state_event( btif_a2dp_sink_focus_state_t state); btif_a2dp_sink_focus_state_t state); static void btif_a2dp_sink_audio_rx_flush_event(); static void btif_a2dp_sink_audio_rx_flush_event(); static void btif_a2dp_sink_clear_track_event_req(); static void btif_a2dp_sink_clear_track_event_req(); static void btif_a2dp_sink_on_start_event(); static void btif_a2dp_sink_on_suspend_event(); UNUSED_ATTR static const char* dump_media_event(uint16_t event) { UNUSED_ATTR static const char* dump_media_event(uint16_t event) { switch (event) { switch (event) { Loading @@ -156,6 +160,8 @@ UNUSED_ATTR static const char* dump_media_event(uint16_t event) { CASE_RETURN_STR(BTIF_MEDIA_SINK_CLEAR_TRACK) CASE_RETURN_STR(BTIF_MEDIA_SINK_CLEAR_TRACK) CASE_RETURN_STR(BTIF_MEDIA_SINK_SET_FOCUS_STATE) CASE_RETURN_STR(BTIF_MEDIA_SINK_SET_FOCUS_STATE) CASE_RETURN_STR(BTIF_MEDIA_SINK_AUDIO_RX_FLUSH) CASE_RETURN_STR(BTIF_MEDIA_SINK_AUDIO_RX_FLUSH) CASE_RETURN_STR(BTIF_MEDIA_SINK_START) CASE_RETURN_STR(BTIF_MEDIA_SINK_SUSPEND) default: default: break; break; } } Loading Loading @@ -364,6 +370,12 @@ static void btif_a2dp_sink_command_ready(BT_HDR* p_msg) { case BTIF_MEDIA_SINK_AUDIO_RX_FLUSH: case BTIF_MEDIA_SINK_AUDIO_RX_FLUSH: btif_a2dp_sink_audio_rx_flush_event(); btif_a2dp_sink_audio_rx_flush_event(); break; break; case BTIF_MEDIA_SINK_START: btif_a2dp_sink_on_start_event(); break; case BTIF_MEDIA_SINK_SUSPEND: btif_a2dp_sink_on_suspend_event(); break; default: default: LOG_ERROR(LOG_TAG, "%s: unknown event %d", __func__, p_msg->event); LOG_ERROR(LOG_TAG, "%s: unknown event %d", __func__, p_msg->event); break; break; Loading Loading @@ -392,6 +404,11 @@ void btif_a2dp_sink_update_decoder(const uint8_t* p_codec_info) { void btif_a2dp_sink_on_idle() { void btif_a2dp_sink_on_idle() { LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__); BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR))); p_buf->event = BTIF_MEDIA_SINK_SUSPEND; btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; btif_a2dp_sink_audio_handle_stop_decoding(); btif_a2dp_sink_audio_handle_stop_decoding(); btif_a2dp_sink_clear_track_event_req(); btif_a2dp_sink_clear_track_event_req(); Loading @@ -399,16 +416,37 @@ void btif_a2dp_sink_on_idle() { void btif_a2dp_sink_on_stopped(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { void btif_a2dp_sink_on_stopped(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__); BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR))); p_buf->event = BTIF_MEDIA_SINK_SUSPEND; btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; btif_a2dp_sink_audio_handle_stop_decoding(); btif_a2dp_sink_audio_handle_stop_decoding(); } } void btif_a2dp_sink_on_suspended(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { void btif_a2dp_sink_on_suspended(UNUSED_ATTR tBTA_AV_SUSPEND* p_av_suspend) { LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__); BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR))); p_buf->event = BTIF_MEDIA_SINK_SUSPEND; btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; if (btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) return; btif_a2dp_sink_audio_handle_stop_decoding(); btif_a2dp_sink_audio_handle_stop_decoding(); } } bool btif_a2dp_sink_on_start() { LOG_INFO(LOG_TAG, "%s", __func__); BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(osi_malloc(sizeof(BT_HDR))); p_buf->event = BTIF_MEDIA_SINK_START; btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); return true; } static void btif_a2dp_sink_audio_handle_stop_decoding() { static void btif_a2dp_sink_audio_handle_stop_decoding() { LOG_INFO(LOG_TAG, "%s", __func__); LOG_INFO(LOG_TAG, "%s", __func__); alarm_t* old_alarm; alarm_t* old_alarm; Loading Loading @@ -592,6 +630,10 @@ static void btif_a2dp_sink_decoder_update_event( return; return; } } if (btif_a2dp_sink_cb.decoder_interface->decoder_configure != nullptr) { btif_a2dp_sink_cb.decoder_interface->decoder_configure(p_buf->codec_info); } APPL_TRACE_DEBUG("%s: create audio track", __func__); APPL_TRACE_DEBUG("%s: create audio track", __func__); btif_a2dp_sink_cb.audio_track = btif_a2dp_sink_cb.audio_track = #ifndef OS_GENERIC #ifndef OS_GENERIC Loading Loading @@ -694,3 +736,25 @@ static void btif_a2dp_sink_clear_track_event_req() { btif_a2dp_sink_cb.worker_thread.DoInThread( btif_a2dp_sink_cb.worker_thread.DoInThread( FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); FROM_HERE, base::BindOnce(btif_a2dp_sink_command_ready, p_buf)); } } static void btif_a2dp_sink_on_start_event() { LOG_INFO(LOG_TAG, "%s", __func__); if ((btif_a2dp_sink_cb.decoder_interface != nullptr) && (btif_a2dp_sink_cb.decoder_interface->decoder_start != nullptr)) { btif_a2dp_sink_cb.decoder_interface->decoder_start(); } return; } static void btif_a2dp_sink_on_suspend_event() { LOG_INFO(LOG_TAG, "%s", __func__); if ((btif_a2dp_sink_cb.decoder_interface != nullptr) && (btif_a2dp_sink_cb.decoder_interface->decoder_suspend != nullptr)) { btif_a2dp_sink_cb.decoder_interface->decoder_suspend(); } return; }
system/btif/src/btif_av.cc +1 −0 Original line number Original line Diff line number Diff line Loading @@ -1869,6 +1869,7 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event, if (peer_.IsSource() && peer_.IsActivePeer()) { if (peer_.IsSource() && peer_.IsActivePeer()) { // Remove flush state, ready for streaming // Remove flush state, ready for streaming btif_a2dp_sink_set_rx_flush(false); btif_a2dp_sink_set_rx_flush(false); btif_a2dp_sink_on_start(); } } if (should_suspend) { if (should_suspend) { Loading
system/stack/a2dp/a2dp_aac.cc +5 −1 Original line number Original line Diff line number Diff line Loading @@ -102,8 +102,12 @@ static const tA2DP_ENCODER_INTERFACE a2dp_encoder_interface_aac = { }; }; static const tA2DP_DECODER_INTERFACE a2dp_decoder_interface_aac = { static const tA2DP_DECODER_INTERFACE a2dp_decoder_interface_aac = { a2dp_aac_decoder_init, a2dp_aac_decoder_cleanup, a2dp_aac_decoder_init, a2dp_aac_decoder_cleanup, a2dp_aac_decoder_decode_packet, a2dp_aac_decoder_decode_packet, nullptr, // decoder_start nullptr, // decoder_suspend nullptr, // decoder_configure }; }; UNUSED_ATTR static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAac( UNUSED_ATTR static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAac( Loading
system/stack/a2dp/a2dp_sbc.cc +5 −1 Original line number Original line Diff line number Diff line Loading @@ -103,8 +103,12 @@ static const tA2DP_ENCODER_INTERFACE a2dp_encoder_interface_sbc = { }; }; static const tA2DP_DECODER_INTERFACE a2dp_decoder_interface_sbc = { static const tA2DP_DECODER_INTERFACE a2dp_decoder_interface_sbc = { a2dp_sbc_decoder_init, a2dp_sbc_decoder_cleanup, a2dp_sbc_decoder_init, a2dp_sbc_decoder_cleanup, a2dp_sbc_decoder_decode_packet, a2dp_sbc_decoder_decode_packet, nullptr, // decoder_start nullptr, // decoder_suspend nullptr, // decoder_configure }; }; static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilitySbc( static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilitySbc( Loading