#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"
/* 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;
/* 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);
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);
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;
}
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
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|.
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|.
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,
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|.
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|.
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|.
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;
};
// 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);
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;
};
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,
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;
};
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;
};
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;
};
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));
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];