From 3b8391cd47dd0ea3e399f99a888f029de8c7d8c8 Mon Sep 17 00:00:00 2001 From: Pavlin Radoslavov Date: Fri, 12 May 2017 01:16:10 -0700 Subject: [PATCH] Set the RTP Header Marker bit selectively per A2DP codec Add a mechanism to set the RTP Header Marker bit per codec. Currently, the Marker bit is set only for AAC. Test: A2DP streaming, PTS AVDTP tests: TC_ACP_SRC_TRA_BTR_BV_01_C, TC_INT_SRC_SIG_SMG_BV_17_C, TC_INT_SRC_TRA_BTR_BV_01_C Bug: 37723283 Change-Id: I9b8e77d44c750746c169df9628d5539ad2406b92 --- bta/av/bta_av_aact.cc | 11 ++++++++++- bta/av/bta_av_int.h | 1 + stack/a2dp/a2dp_aac.cc | 2 ++ stack/a2dp/a2dp_sbc.cc | 7 +++++++ stack/a2dp/a2dp_vendor_aptx.cc | 2 ++ stack/a2dp/a2dp_vendor_aptx_hd.cc | 2 ++ stack/a2dp/a2dp_vendor_ldac.cc | 2 ++ stack/include/a2dp_aac.h | 2 +- stack/include/a2dp_codec_api.h | 7 +++++++ stack/include/a2dp_sbc.h | 3 ++- stack/include/a2dp_vendor_aptx.h | 2 +- stack/include/a2dp_vendor_aptx_hd.h | 2 +- stack/include/a2dp_vendor_ldac.h | 2 +- stack/test/stack_a2dp_test.cc | 2 ++ 14 files changed, 41 insertions(+), 6 deletions(-) diff --git a/bta/av/bta_av_aact.cc b/bta/av/bta_av_aact.cc index defe9fbca..3bf6f8e65 100644 --- a/bta/av/bta_av_aact.cc +++ b/bta/av/bta_av_aact.cc @@ -33,6 +33,7 @@ #include "avdt_api.h" #include "bt_utils.h" #include "bta_av_int.h" +#include "btif/include/btif_av_co.h" #include "l2c_api.h" #include "l2cdefs.h" #include "osi/include/osi.h" @@ -1024,6 +1025,7 @@ void bta_av_cleanup(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { /* if de-registering shut everything down */ msg.hdr.layer_specific = p_scb->hndl; p_scb->started = false; + p_scb->current_codec = nullptr; p_scb->cong = false; p_scb->role = role; p_scb->cur_psc_mask = 0; @@ -1454,6 +1456,7 @@ void bta_av_do_close(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { /* close stream */ p_scb->started = false; + p_scb->current_codec = nullptr; /* drop the buffers queued in L2CAP */ L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_ALL); @@ -2095,11 +2098,15 @@ void bta_av_data_path(tBTA_AV_SCB* p_scb, UNUSED_ATTR tBTA_AV_DATA* p_data) { BT_HDR* p_buf = NULL; uint32_t timestamp; bool new_buf = false; - uint8_t m_pt = AVDT_MARKER_SET | 0x60; + uint8_t m_pt = 0x60; tAVDT_DATA_OPT_MASK opt; if (p_scb->cong) return; + if (p_scb->current_codec->useRtpHeaderMarkerBit()) { + m_pt |= AVDT_MARKER_SET; + } + // Always get the current number of bufs que'd up p_scb->l2c_bufs = (uint8_t)L2CA_FlushChannel(p_scb->l2c_cid, L2CAP_FLUSH_CHANS_GET); @@ -2225,6 +2232,8 @@ void bta_av_start_ok(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { p_scb->role); p_scb->started = true; + p_scb->current_codec = bta_av_get_a2dp_current_codec(); + if (p_scb->sco_suspend) { p_scb->sco_suspend = false; } diff --git a/bta/av/bta_av_int.h b/bta/av/bta_av_int.h index 394562e5c..e1237bbfc 100644 --- a/bta/av/bta_av_int.h +++ b/bta/av/bta_av_int.h @@ -482,6 +482,7 @@ typedef struct { uint8_t rc_handle; /* connected AVRCP handle */ bool use_rc; /* true if AVRCP is allowed */ bool started; /* true if stream started */ + A2dpCodecConfig* current_codec; /* The current A2DP codec */ uint8_t co_started; /* non-zero, if stream started from call-out perspective */ bool recfg_sup; /* true if the first attempt to reconfigure the stream was diff --git a/stack/a2dp/a2dp_aac.cc b/stack/a2dp/a2dp_aac.cc index 6c0accd2d..8fc803497 100644 --- a/stack/a2dp/a2dp_aac.cc +++ b/stack/a2dp/a2dp_aac.cc @@ -706,6 +706,8 @@ bool A2dpCodecConfigAac::init() { return true; } +bool A2dpCodecConfigAac::useRtpHeaderMarkerBit() const { return true; } + // // Selects the best sample rate from |sampleRate|. // The result is stored in |p_result| and |p_codec_config|. diff --git a/stack/a2dp/a2dp_sbc.cc b/stack/a2dp/a2dp_sbc.cc index 1a732587f..5e3b6afaa 100644 --- a/stack/a2dp/a2dp_sbc.cc +++ b/stack/a2dp/a2dp_sbc.cc @@ -1056,6 +1056,8 @@ bool A2dpCodecConfigSbc::init() { return true; } +bool A2dpCodecConfigSbc::useRtpHeaderMarkerBit() const { return false; } + // // Selects the best sample rate from |samp_freq|. // The result is stored in |p_result| and |p_codec_config|. @@ -1610,6 +1612,11 @@ bool A2dpCodecConfigSbcSink::init() { return true; } +bool A2dpCodecConfigSbcSink::useRtpHeaderMarkerBit() const { + // TODO: This method applies only to Source codecs + return false; +} + bool A2dpCodecConfigSbcSink::setCodecConfig( UNUSED_ATTR const uint8_t* p_peer_codec_info, UNUSED_ATTR bool is_capability, diff --git a/stack/a2dp/a2dp_vendor_aptx.cc b/stack/a2dp/a2dp_vendor_aptx.cc index 1941393bd..c624af2b1 100644 --- a/stack/a2dp/a2dp_vendor_aptx.cc +++ b/stack/a2dp/a2dp_vendor_aptx.cc @@ -436,6 +436,8 @@ bool A2dpCodecConfigAptx::init() { return true; } +bool A2dpCodecConfigAptx::useRtpHeaderMarkerBit() const { return false; } + // // Selects the best sample rate from |sampleRate|. // The result is stored in |p_result| and p_codec_config|. diff --git a/stack/a2dp/a2dp_vendor_aptx_hd.cc b/stack/a2dp/a2dp_vendor_aptx_hd.cc index 798f90831..4f1c8d26f 100644 --- a/stack/a2dp/a2dp_vendor_aptx_hd.cc +++ b/stack/a2dp/a2dp_vendor_aptx_hd.cc @@ -453,6 +453,8 @@ bool A2dpCodecConfigAptxHd::init() { return true; } +bool A2dpCodecConfigAptxHd::useRtpHeaderMarkerBit() const { return false; } + // // Selects the best sample rate from |sampleRate|. // The result is stored in |p_result| and p_codec_config|. diff --git a/stack/a2dp/a2dp_vendor_ldac.cc b/stack/a2dp/a2dp_vendor_ldac.cc index 82d93d24b..072173af6 100644 --- a/stack/a2dp/a2dp_vendor_ldac.cc +++ b/stack/a2dp/a2dp_vendor_ldac.cc @@ -558,6 +558,8 @@ bool A2dpCodecConfigLdac::init() { return true; } +bool A2dpCodecConfigLdac::useRtpHeaderMarkerBit() const { return false; } + // // Selects the best sample rate from |sampleRate|. // The result is stored in |p_result| and |p_codec_config|. diff --git a/stack/include/a2dp_aac.h b/stack/include/a2dp_aac.h index cc67a152e..88bb1d941 100644 --- a/stack/include/a2dp_aac.h +++ b/stack/include/a2dp_aac.h @@ -36,11 +36,11 @@ class A2dpCodecConfigAac : public A2dpCodecConfig { uint8_t* p_result_codec_config) override; private: + bool useRtpHeaderMarkerBit() const override; bool updateEncoderUserConfig( const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params, bool* p_restart_input, bool* p_restart_output, bool* p_config_updated) override; - void debug_codec_dump(int fd) override; }; diff --git a/stack/include/a2dp_codec_api.h b/stack/include/a2dp_codec_api.h index 794450831..816262840 100644 --- a/stack/include/a2dp_codec_api.h +++ b/stack/include/a2dp_codec_api.h @@ -107,6 +107,13 @@ class A2dpCodecConfig { // or 0 if not configured. uint8_t getAudioBitsPerSample(); + // Checks whether the codec uses the RTP Header Marker bit (see RFC 6416). + // NOTE: Even if the encoded data uses RTP headers, some codecs do not use + // the Marker bit - that bit is expected to be set to 0. + // Returns true if the encoded data packets have RTP headers, and + // the Marker bit in the header is set according to RFC 6416. + virtual bool useRtpHeaderMarkerBit() const = 0; + // Checks whether |codec_config| is empty and contains no configuration. // Returns true if |codec_config| is empty, otherwise false. static bool isCodecConfigEmpty(const btav_a2dp_codec_config_t& codec_config); diff --git a/stack/include/a2dp_sbc.h b/stack/include/a2dp_sbc.h index b6379fdd8..ea06312e6 100644 --- a/stack/include/a2dp_sbc.h +++ b/stack/include/a2dp_sbc.h @@ -36,11 +36,11 @@ class A2dpCodecConfigSbc : public A2dpCodecConfig { uint8_t* p_result_codec_config) override; private: + bool useRtpHeaderMarkerBit() const override; bool updateEncoderUserConfig( const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params, bool* p_restart_input, bool* p_restart_output, bool* p_config_updated) override; - void debug_codec_dump(int fd) override; }; @@ -55,6 +55,7 @@ class A2dpCodecConfigSbcSink : public A2dpCodecConfig { uint8_t* p_result_codec_config) override; private: + bool useRtpHeaderMarkerBit() const override; bool updateEncoderUserConfig( const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params, bool* p_restart_input, bool* p_restart_output, diff --git a/stack/include/a2dp_vendor_aptx.h b/stack/include/a2dp_vendor_aptx.h index a3f8c3934..1fba23af8 100644 --- a/stack/include/a2dp_vendor_aptx.h +++ b/stack/include/a2dp_vendor_aptx.h @@ -36,11 +36,11 @@ class A2dpCodecConfigAptx : public A2dpCodecConfig { uint8_t* p_result_codec_config) override; private: + bool useRtpHeaderMarkerBit() const override; bool updateEncoderUserConfig( const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params, bool* p_restart_input, bool* p_restart_output, bool* p_config_updated) override; - void debug_codec_dump(int fd) override; }; diff --git a/stack/include/a2dp_vendor_aptx_hd.h b/stack/include/a2dp_vendor_aptx_hd.h index 688f44089..0250ca018 100644 --- a/stack/include/a2dp_vendor_aptx_hd.h +++ b/stack/include/a2dp_vendor_aptx_hd.h @@ -36,11 +36,11 @@ class A2dpCodecConfigAptxHd : public A2dpCodecConfig { uint8_t* p_result_codec_config) override; private: + bool useRtpHeaderMarkerBit() const override; bool updateEncoderUserConfig( const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params, bool* p_restart_input, bool* p_restart_output, bool* p_config_updated) override; - void debug_codec_dump(int fd) override; }; diff --git a/stack/include/a2dp_vendor_ldac.h b/stack/include/a2dp_vendor_ldac.h index 2bf0da01a..a4dd48db3 100644 --- a/stack/include/a2dp_vendor_ldac.h +++ b/stack/include/a2dp_vendor_ldac.h @@ -36,11 +36,11 @@ class A2dpCodecConfigLdac : public A2dpCodecConfig { uint8_t* p_result_codec_config) override; private: + bool useRtpHeaderMarkerBit() const override; bool updateEncoderUserConfig( const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params, bool* p_restart_input, bool* p_restart_output, bool* p_config_updated) override; - void debug_codec_dump(int fd) override; }; diff --git a/stack/test/stack_a2dp_test.cc b/stack/test/stack_a2dp_test.cc index ef4616690..7785909a5 100644 --- a/stack/test/stack_a2dp_test.cc +++ b/stack/test/stack_a2dp_test.cc @@ -867,6 +867,7 @@ TEST_F(A2dpCodecConfigTest, setCodecConfig) { for (size_t i = 0; i < codec_info_sbc[0] + 1; i++) { EXPECT_EQ(codec_info_result[i], codec_info_sbc[i]); } + EXPECT_FALSE(codec_config->useRtpHeaderMarkerBit()); // Create the codec config - AAC memset(codec_info_result, 0, sizeof(codec_info_result)); @@ -882,6 +883,7 @@ TEST_F(A2dpCodecConfigTest, setCodecConfig) { for (size_t i = 0; i < codec_info_aac[0] + 1; i++) { EXPECT_EQ(codec_info_result[i], codec_info_aac[i]); } + EXPECT_TRUE(codec_config->useRtpHeaderMarkerBit()); // Test invalid codec info uint8_t codec_info_sbc_test1[AVDT_CODEC_SIZE]; -- 2.11.0