From 67ae84fb7f01d8458bfc1dcb506f32e7d9350d17 Mon Sep 17 00:00:00 2001 From: Pavlin Radoslavov Date: Thu, 6 Apr 2017 15:13:16 -0700 Subject: [PATCH] Add A2DP codec-specific information to dumpsys output Now we print the following information: * Current codec name * Info for each supported codec: - Priority - Encoder interval (ms) - Codec Config: Sampling rate, Bits per sample, Channel mode (MONO/STEREO) - Selectable codec configuration - Codec's local capability - Packet counts (expected/dropped) - PCM read counts (expected/actual) - PCM read bytes (expected/actual) * LDAC codec-specific info: - LDAC quality mode: HIGH/MID/LOW/ABR - LDAC saved transmit queue length [used in ABR mode] * SBC codec-specific info: - Frames counts (expected/dropped) Sample of the new format is below: --- A2DP Codecs State: Current Codec: LDAC A2DP LDAC State: Priority: 1000000 Encoder interval (ms): 20 Config: Rate=96000 Bits=32 Mode=STEREO Selectable: Rate=44100|48000|88200|96000 Bits=16|24|32 Mode=MONO|STEREO Local capability: Rate=44100|48000|88200|96000 Bits=16|24|32 Mode=MONO|STEREO Packet counts (expected/dropped) : 596 / 161 PCM read counts (expected/actual) : 2488 / 2488 PCM read bytes (expected/actual) : 2547712 / 2547712 LDAC quality mode : ABR LDAC saved transmit queue length : 0 A2DP aptX-HD State: Priority: 4001 Encoder interval (ms): 0 Config: Invalid Selectable: Invalid Local capability: Rate=44100|48000 Bits=24 Mode=STEREO Packet counts (expected/dropped) : 0 / 0 PCM read counts (expected/actual) : 0 / 0 PCM read bytes (expected/actual) : 0 / 0 A2DP aptX State: Priority: 3001 Encoder interval (ms): 0 Config: Rate=44100 Bits=16 Mode=STEREO Selectable: Rate=44100|48000 Bits=16 Mode=STEREO Local capability: Rate=44100|48000 Bits=16 Mode=STEREO Packet counts (expected/dropped) : 0 / 0 PCM read counts (expected/actual) : 0 / 0 PCM read bytes (expected/actual) : 0 / 0 A2DP AAC State: Priority: 2001 Encoder interval (ms): 20 Config: Rate=44100 Bits=16 Mode=STEREO Selectable: Rate=44100|48000 Bits=16 Mode=STEREO Local capability: Rate=44100|48000|88200|96000 Bits=16 Mode=STEREO Packet counts (expected/dropped) : 0 / 0 PCM read counts (expected/actual) : 0 / 0 PCM read bytes (expected/actual) : 0 / 0 A2DP SBC State: Priority: 1001 Encoder interval (ms): 20 Config: Rate=44100 Bits=16 Mode=STEREO Selectable: Rate=44100 Bits=16 Mode=STEREO Local capability: Rate=44100 Bits=16 Mode=STEREO Packet counts (expected/dropped) : 580 / 0 PCM read counts (expected/actual) : 2900 / 2900 PCM read bytes (expected/actual) : 1484800 / 1484800 Frames counts (expected/dropped) : 3724 / 0 --- Bug: 36567128 Test: Stream A2DP and "adb shell dumpsys bluetooth_manager" Change-Id: Idd86005b842a4e569b7df91b8bbaf0632ed7f7c9 (cherry picked from commit 302113d4e44f06e90f90a5903e33ae830edb58a3) --- btif/src/btif_a2dp_source.cc | 6 +- stack/a2dp/a2dp_aac.cc | 4 +- stack/a2dp/a2dp_aac_encoder.cc | 34 ++++--- stack/a2dp/a2dp_codec_config.cc | 142 ++++++++++++++++++++++++++++ stack/a2dp/a2dp_sbc.cc | 9 +- stack/a2dp/a2dp_sbc_encoder.cc | 103 ++++++++++---------- stack/a2dp/a2dp_vendor_aptx.cc | 4 +- stack/a2dp/a2dp_vendor_aptx_encoder.cc | 14 ++- stack/a2dp/a2dp_vendor_aptx_hd.cc | 4 +- stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc | 14 ++- stack/a2dp/a2dp_vendor_ldac.cc | 3 +- stack/a2dp/a2dp_vendor_ldac_encoder.cc | 40 ++++---- stack/include/a2dp_aac.h | 3 + stack/include/a2dp_aac_encoder.h | 5 - stack/include/a2dp_codec_api.h | 51 ++++++++-- stack/include/a2dp_sbc.h | 4 + stack/include/a2dp_sbc_encoder.h | 5 - stack/include/a2dp_vendor_aptx.h | 3 + stack/include/a2dp_vendor_aptx_encoder.h | 5 - stack/include/a2dp_vendor_aptx_hd.h | 3 + stack/include/a2dp_vendor_aptx_hd_encoder.h | 5 - stack/include/a2dp_vendor_ldac.h | 3 + stack/include/a2dp_vendor_ldac_encoder.h | 5 - 23 files changed, 338 insertions(+), 131 deletions(-) diff --git a/btif/src/btif_a2dp_source.cc b/btif/src/btif_a2dp_source.cc index 6be76aa43..610437056 100644 --- a/btif/src/btif_a2dp_source.cc +++ b/btif/src/btif_a2dp_source.cc @@ -1024,8 +1024,10 @@ void btif_a2dp_source_debug_dump(int fd) { // // Codec-specific stats // - if (btif_a2dp_source_cb.encoder_interface != NULL) - btif_a2dp_source_cb.encoder_interface->debug_codec_dump(fd); + A2dpCodecs* a2dp_codecs = bta_av_get_a2dp_codecs(); + if (a2dp_codecs != nullptr) { + a2dp_codecs->debug_codec_dump(fd); + } } void btif_a2dp_source_update_metrics(void) { diff --git a/stack/a2dp/a2dp_aac.cc b/stack/a2dp/a2dp_aac.cc index 87526eb2d..71f61eaf4 100644 --- a/stack/a2dp/a2dp_aac.cc +++ b/stack/a2dp/a2dp_aac.cc @@ -82,8 +82,8 @@ static const tA2DP_ENCODER_INTERFACE a2dp_encoder_interface_aac = { a2dp_aac_feeding_flush, a2dp_aac_get_encoder_interval_ms, a2dp_aac_send_frames, - nullptr, // set_transmit_queue_length - a2dp_aac_debug_codec_dump}; + nullptr // set_transmit_queue_length +}; UNUSED_ATTR static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAac( const tA2DP_AAC_CIE* p_cap, const uint8_t* p_codec_info, diff --git a/stack/a2dp/a2dp_aac_encoder.cc b/stack/a2dp/a2dp_aac_encoder.cc index 54c621f18..4bfe03164 100644 --- a/stack/a2dp/a2dp_aac_encoder.cc +++ b/stack/a2dp/a2dp_aac_encoder.cc @@ -34,12 +34,6 @@ // Encoder for AAC Source Codec // -#define STATS_UPDATE_MAX(current_value_storage, new_value) \ - do { \ - if ((new_value) > (current_value_storage)) \ - (current_value_storage) = (new_value); \ - } while (0) - // A2DP AAC encoder interval in milliseconds #define A2DP_AAC_ENCODER_INTERVAL_MS 20 @@ -575,15 +569,16 @@ static void a2dp_aac_encode_frames(uint8_t nb_frame) { while (nb_frame) { BT_HDR* p_buf = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE); - - /* Init buffer */ p_buf->offset = A2DP_AAC_OFFSET; p_buf->len = 0; p_buf->layer_specific = 0; + a2dp_aac_encoder_cb.stats.media_read_total_expected_packets++; count = 0; do { - /* Read PCM data */ + // + // Read the PCM data and encode it + // if (a2dp_aac_read_feeding(read_buffer)) { uint8_t* packet = (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len; if (!a2dp_aac_encoder_cb.has_aac_handle) { @@ -637,6 +632,7 @@ static void a2dp_aac_encode_frames(uint8_t nb_frame) { remain_nb_frame = nb_frame; if (!a2dp_aac_encoder_cb.enqueue_callback(p_buf, done_nb_frame)) return; } else { + a2dp_aac_encoder_cb.stats.media_read_total_dropped_packets++; osi_free(p_buf); } } @@ -647,9 +643,13 @@ static bool a2dp_aac_read_feeding(uint8_t* read_buffer) { a2dp_aac_encoder_cb.feeding_params.channel_count * a2dp_aac_encoder_cb.feeding_params.bits_per_sample / 8; + a2dp_aac_encoder_cb.stats.media_read_total_expected_reads_count++; + a2dp_aac_encoder_cb.stats.media_read_total_expected_read_bytes += read_size; + /* Read Data from UIPC channel */ uint32_t nb_byte_read = a2dp_aac_encoder_cb.read_callback(read_buffer, read_size); + a2dp_aac_encoder_cb.stats.media_read_total_actual_read_bytes += nb_byte_read; if (nb_byte_read < read_size) { if (nb_byte_read == 0) return false; @@ -658,28 +658,34 @@ static bool a2dp_aac_read_feeding(uint8_t* read_buffer) { memset(((uint8_t*)read_buffer) + nb_byte_read, 0, read_size - nb_byte_read); nb_byte_read = read_size; } + a2dp_aac_encoder_cb.stats.media_read_total_actual_reads_count++; + return true; } -void a2dp_aac_debug_codec_dump(int fd) { +period_ms_t A2dpCodecConfigAac::encoderIntervalMs() const { + return a2dp_aac_get_encoder_interval_ms(); +} + +void A2dpCodecConfigAac::debug_codec_dump(int fd) { a2dp_aac_encoder_stats_t* stats = &a2dp_aac_encoder_cb.stats; - dprintf(fd, "\nA2DP AAC State:\n"); + A2dpCodecConfig::debug_codec_dump(fd); dprintf(fd, - " Packets expected/dropped : %zu / " + " Packet counts (expected/dropped) : %zu / " "%zu\n", stats->media_read_total_expected_packets, stats->media_read_total_dropped_packets); dprintf(fd, - " PCM reads count expected/actual : %zu / " + " PCM read counts (expected/actual) : %zu / " "%zu\n", stats->media_read_total_expected_reads_count, stats->media_read_total_actual_reads_count); dprintf(fd, - " PCM read bytes expected/actual : %zu / " + " PCM read bytes (expected/actual) : %zu / " "%zu\n", stats->media_read_total_expected_read_bytes, stats->media_read_total_actual_read_bytes); diff --git a/stack/a2dp/a2dp_codec_config.cc b/stack/a2dp/a2dp_codec_config.cc index 9a117efcc..e5f06d6d9 100644 --- a/stack/a2dp/a2dp_codec_config.cc +++ b/stack/a2dp/a2dp_codec_config.cc @@ -23,6 +23,7 @@ #include "a2dp_codec_api.h" #include +#include #include "a2dp_aac.h" #include "a2dp_sbc.h" @@ -282,6 +283,130 @@ bool A2dpCodecConfig::setCodecUserConfig( return true; } +bool A2dpCodecConfig::codecConfigIsValid( + const btav_a2dp_codec_config_t& codec_config) { + return (codec_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) && + (codec_config.sample_rate != BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) && + (codec_config.bits_per_sample != + BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) && + (codec_config.channel_mode != BTAV_A2DP_CODEC_CHANNEL_MODE_NONE); +} + +std::string A2dpCodecConfig::codecConfig2Str( + const btav_a2dp_codec_config_t& codec_config) { + std::string result; + + if (!codecConfigIsValid(codec_config)) return "Invalid"; + + result.append("Rate="); + result.append(codecSampleRate2Str(codec_config.sample_rate)); + result.append(" Bits="); + result.append(codecBitsPerSample2Str(codec_config.bits_per_sample)); + result.append(" Mode="); + result.append(codecChannelMode2Str(codec_config.channel_mode)); + + return result; +} + +std::string A2dpCodecConfig::codecSampleRate2Str( + btav_a2dp_codec_sample_rate_t codec_sample_rate) { + std::string result; + + if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_44100) { + if (!result.empty()) result += "|"; + result += "44100"; + } + if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_48000) { + if (!result.empty()) result += "|"; + result += "48000"; + } + if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_88200) { + if (!result.empty()) result += "|"; + result += "88200"; + } + if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_96000) { + if (!result.empty()) result += "|"; + result += "96000"; + } + if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_176400) { + if (!result.empty()) result += "|"; + result += "176400"; + } + if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_192000) { + if (!result.empty()) result += "|"; + result += "192000"; + } + if (result.empty()) { + std::stringstream ss; + ss << "UnknownSampleRate(0x" << std::hex << codec_sample_rate << ")"; + ss >> result; + } + + return result; +} + +std::string A2dpCodecConfig::codecBitsPerSample2Str( + btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample) { + std::string result; + + if (codec_bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16) { + if (!result.empty()) result += "|"; + result += "16"; + } + if (codec_bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24) { + if (!result.empty()) result += "|"; + result += "24"; + } + if (codec_bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32) { + if (!result.empty()) result += "|"; + result += "32"; + } + if (result.empty()) { + std::stringstream ss; + ss << "UnknownBitsPerSample(0x" << std::hex << codec_bits_per_sample << ")"; + ss >> result; + } + + return result; +} + +std::string A2dpCodecConfig::codecChannelMode2Str( + btav_a2dp_codec_channel_mode_t codec_channel_mode) { + std::string result; + + if (codec_channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_MONO) { + if (!result.empty()) result += "|"; + result += "MONO"; + } + if (codec_channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO) { + if (!result.empty()) result += "|"; + result += "STEREO"; + } + if (result.empty()) { + std::stringstream ss; + ss << "UnknownChannelMode(0x" << std::hex << codec_channel_mode << ")"; + ss >> result; + } + + return result; +} + +void A2dpCodecConfig::debug_codec_dump(int fd) { + std::string result; + dprintf(fd, "\nA2DP %s State:\n", name().c_str()); + dprintf(fd, " Priority: %d\n", codecPriority()); + dprintf(fd, " Encoder interval (ms): %" PRIu64 "\n", encoderIntervalMs()); + + result = codecConfig2Str(getCodecConfig()); + dprintf(fd, " Config: %s\n", result.c_str()); + + result = codecConfig2Str(getCodecSelectableCapability()); + dprintf(fd, " Selectable: %s\n", result.c_str()); + + result = codecConfig2Str(getCodecLocalCapability()); + dprintf(fd, " Local capability: %s\n", result.c_str()); +} + // // Compares two codecs |lhs| and |rhs| based on their priority. // Returns true if |lhs| has higher priority (larger priority value). @@ -668,6 +793,23 @@ bool A2dpCodecs::getCodecConfigAndCapabilities( return true; } +void A2dpCodecs::debug_codec_dump(int fd) { + std::lock_guard lock(codec_mutex_); + dprintf(fd, "\nA2DP Codecs State:\n"); + + // Print the current codec name + if (current_codec_config_ != nullptr) { + dprintf(fd, " Current Codec: %s\n", current_codec_config_->name().c_str()); + } else { + dprintf(fd, " Current Codec: None\n"); + } + + // Print the codec-specific state + for (auto codec_config : ordered_source_codecs_) { + codec_config->debug_codec_dump(fd); + } +} + tA2DP_CODEC_TYPE A2DP_GetCodecType(const uint8_t* p_codec_info) { return (tA2DP_CODEC_TYPE)(p_codec_info[AVDT_CODEC_TYPE_INDEX]); } diff --git a/stack/a2dp/a2dp_sbc.cc b/stack/a2dp/a2dp_sbc.cc index ef35ebddd..55ab165b2 100644 --- a/stack/a2dp/a2dp_sbc.cc +++ b/stack/a2dp/a2dp_sbc.cc @@ -97,8 +97,8 @@ static const tA2DP_ENCODER_INTERFACE a2dp_encoder_interface_sbc = { a2dp_sbc_feeding_flush, a2dp_sbc_get_encoder_interval_ms, a2dp_sbc_send_frames, - nullptr, // set_transmit_queue_length - a2dp_sbc_debug_codec_dump}; + nullptr // set_transmit_queue_length +}; static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilitySbc( const tA2DP_SBC_CIE* p_cap, const uint8_t* p_codec_info, @@ -1638,3 +1638,8 @@ bool A2dpCodecConfigSbcSink::updateEncoderUserConfig( // TODO: This method applies only to Source codecs return false; } + +period_ms_t A2dpCodecConfigSbcSink::encoderIntervalMs() const { + // TODO: This method applies only to Source codecs + return 0; +} diff --git a/stack/a2dp/a2dp_sbc_encoder.cc b/stack/a2dp/a2dp_sbc_encoder.cc index 551846179..939a68a23 100644 --- a/stack/a2dp/a2dp_sbc_encoder.cc +++ b/stack/a2dp/a2dp_sbc_encoder.cc @@ -32,12 +32,6 @@ #include "osi/include/log.h" #include "osi/include/osi.h" -#define STATS_UPDATE_MAX(current_value_storage, new_value) \ - do { \ - if ((new_value) > (current_value_storage)) \ - (current_value_storage) = (new_value); \ - } while (0) - /* Buffer pool */ #define A2DP_SBC_BUFFER_SIZE BT_DEFAULT_BUFFER_SIZE @@ -88,13 +82,16 @@ typedef struct { typedef struct { uint64_t session_start_us; - size_t media_read_total_expected_frames; - size_t media_read_max_expected_frames; - size_t media_read_expected_count; + size_t media_read_total_expected_packets; + size_t media_read_total_expected_reads_count; + size_t media_read_total_expected_read_bytes; + + size_t media_read_total_dropped_packets; + size_t media_read_total_actual_reads_count; + size_t media_read_total_actual_read_bytes; - size_t media_read_total_limited_frames; - size_t media_read_max_limited_frames; - size_t media_read_limited_count; + size_t media_read_total_expected_frames; + size_t media_read_total_dropped_frames; } a2dp_sbc_encoder_stats_t; typedef struct { @@ -452,10 +449,7 @@ static void a2dp_sbc_get_num_frame_iteration(uint8_t* num_of_iterations, projected_nof = a2dp_sbc_encoder_cb.feeding_state.counter / pcm_bytes_per_frame; // Update the stats - STATS_UPDATE_MAX(a2dp_sbc_encoder_cb.stats.media_read_max_expected_frames, - projected_nof); a2dp_sbc_encoder_cb.stats.media_read_total_expected_frames += projected_nof; - a2dp_sbc_encoder_cb.stats.media_read_expected_count++; if (projected_nof > MAX_PCM_FRAME_NUM_PER_TICK) { LOG_WARN(LOG_TAG, "%s: limiting frames to be sent from %d to %d", __func__, @@ -463,10 +457,7 @@ static void a2dp_sbc_get_num_frame_iteration(uint8_t* num_of_iterations, // Update the stats size_t delta = projected_nof - MAX_PCM_FRAME_NUM_PER_TICK; - a2dp_sbc_encoder_cb.stats.media_read_limited_count++; - a2dp_sbc_encoder_cb.stats.media_read_total_limited_frames += delta; - STATS_UPDATE_MAX(a2dp_sbc_encoder_cb.stats.media_read_max_limited_frames, - delta); + a2dp_sbc_encoder_cb.stats.media_read_total_dropped_frames += delta; projected_nof = MAX_PCM_FRAME_NUM_PER_TICK; } @@ -512,6 +503,11 @@ static void a2dp_sbc_get_num_frame_iteration(uint8_t* num_of_iterations, if (projected_nof > MAX_PCM_FRAME_NUM_PER_TICK) { LOG_ERROR(LOG_TAG, "%s: Audio Congestion (frames: %d > max (%d))", __func__, projected_nof, MAX_PCM_FRAME_NUM_PER_TICK); + + // Update the stats + size_t delta = projected_nof - MAX_PCM_FRAME_NUM_PER_TICK; + a2dp_sbc_encoder_cb.stats.media_read_total_dropped_frames += delta; + projected_nof = MAX_PCM_FRAME_NUM_PER_TICK; a2dp_sbc_encoder_cb.feeding_state.counter = noi * projected_nof * pcm_bytes_per_frame; @@ -535,18 +531,19 @@ static void a2dp_sbc_encode_frames(uint8_t nb_frame) { uint8_t last_frame_len = 0; while (nb_frame) { BT_HDR* p_buf = (BT_HDR*)osi_malloc(A2DP_SBC_BUFFER_SIZE); - - /* Init buffer */ p_buf->offset = A2DP_SBC_OFFSET; p_buf->len = 0; p_buf->layer_specific = 0; + a2dp_sbc_encoder_cb.stats.media_read_total_expected_packets++; do { /* Fill allocated buffer with 0 */ memset(a2dp_sbc_encoder_cb.pcmBuffer, 0, blocm_x_subband * p_encoder_params->s16NumOfChannels); - /* Read PCM data and upsample them if needed */ + // + // Read the PCM data and encode it. If necessary, upsample the data. + // if (a2dp_sbc_read_feeding()) { uint8_t* output = (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len; int16_t* input = a2dp_sbc_encoder_cb.pcmBuffer; @@ -585,6 +582,7 @@ static void a2dp_sbc_encode_frames(uint8_t nb_frame) { remain_nb_frame = nb_frame; if (!a2dp_sbc_encoder_cb.enqueue_callback(p_buf, done_nb_frame)) return; } else { + a2dp_sbc_encoder_cb.stats.media_read_total_dropped_packets++; osi_free(p_buf); } } @@ -629,17 +627,23 @@ static bool a2dp_sbc_read_feeding(void) { break; } + a2dp_sbc_encoder_cb.stats.media_read_total_expected_reads_count++; if (sbc_sampling == a2dp_sbc_encoder_cb.feeding_params.sample_rate) { read_size = bytes_needed - a2dp_sbc_encoder_cb.feeding_state.aa_feed_residue; + a2dp_sbc_encoder_cb.stats.media_read_total_expected_read_bytes += read_size; nb_byte_read = a2dp_sbc_encoder_cb.read_callback( ((uint8_t*)a2dp_sbc_encoder_cb.pcmBuffer) + a2dp_sbc_encoder_cb.feeding_state.aa_feed_residue, read_size); + a2dp_sbc_encoder_cb.stats.media_read_total_actual_read_bytes += + nb_byte_read; + if (nb_byte_read != read_size) { a2dp_sbc_encoder_cb.feeding_state.aa_feed_residue += nb_byte_read; return false; } + a2dp_sbc_encoder_cb.stats.media_read_total_actual_reads_count++; a2dp_sbc_encoder_cb.feeding_state.aa_feed_residue = 0; return true; } @@ -686,10 +690,12 @@ static bool a2dp_sbc_read_feeding(void) { read_size = src_samples; read_size *= a2dp_sbc_encoder_cb.feeding_params.channel_count; read_size *= (a2dp_sbc_encoder_cb.feeding_params.bits_per_sample / 8); + a2dp_sbc_encoder_cb.stats.media_read_total_expected_read_bytes += read_size; /* Read Data from UIPC channel */ nb_byte_read = a2dp_sbc_encoder_cb.read_callback((uint8_t*)read_buffer, read_size); + a2dp_sbc_encoder_cb.stats.media_read_total_actual_read_bytes += nb_byte_read; if (nb_byte_read < read_size) { if (nb_byte_read == 0) return false; @@ -698,6 +704,7 @@ static bool a2dp_sbc_read_feeding(void) { memset(((uint8_t*)read_buffer) + nb_byte_read, 0, read_size - nb_byte_read); nb_byte_read = read_size; } + a2dp_sbc_encoder_cb.stats.media_read_total_actual_reads_count++; /* Initialize PCM up-sampling engine */ a2dp_sbc_init_up_sample(a2dp_sbc_encoder_cb.feeding_params.sample_rate, @@ -879,36 +886,36 @@ static uint32_t a2dp_sbc_frame_length(void) { return frame_len; } -void a2dp_sbc_debug_codec_dump(int fd) { +period_ms_t A2dpCodecConfigSbc::encoderIntervalMs() const { + return a2dp_sbc_get_encoder_interval_ms(); +} + +void A2dpCodecConfigSbc::debug_codec_dump(int fd) { a2dp_sbc_encoder_stats_t* stats = &a2dp_sbc_encoder_cb.stats; - size_t ave_size; - dprintf(fd, "\nA2DP SBC State:\n"); + A2dpCodecConfig::debug_codec_dump(fd); - ave_size = 0; - if (stats->media_read_expected_count != 0) { - ave_size = stats->media_read_total_expected_frames / - stats->media_read_expected_count; - } dprintf(fd, - " Frames expected (total/max/ave) : %zu / " - "%zu / %zu\n", - stats->media_read_total_expected_frames, - stats->media_read_max_expected_frames, ave_size); + " Packet counts (expected/dropped) : %zu / " + "%zu\n", + stats->media_read_total_expected_packets, + stats->media_read_total_dropped_packets); - ave_size = 0; - if (stats->media_read_limited_count != 0) { - ave_size = stats->media_read_total_limited_frames / - stats->media_read_limited_count; - } dprintf(fd, - " Frames limited (total/max/ave) : %zu / " - "%zu / %zu\n", - stats->media_read_total_limited_frames, - stats->media_read_max_limited_frames, ave_size); - - dprintf( - fd, - " Counts (expected/limited) : %zu / %zu\n", - stats->media_read_expected_count, stats->media_read_limited_count); + " PCM read counts (expected/actual) : %zu / " + "%zu\n", + stats->media_read_total_expected_reads_count, + stats->media_read_total_actual_reads_count); + + dprintf(fd, + " PCM read bytes (expected/actual) : %zu / " + "%zu\n", + stats->media_read_total_expected_read_bytes, + stats->media_read_total_actual_read_bytes); + + dprintf(fd, + " Frames counts (expected/dropped) : %zu / " + "%zu\n", + stats->media_read_total_expected_frames, + stats->media_read_total_dropped_frames); } diff --git a/stack/a2dp/a2dp_vendor_aptx.cc b/stack/a2dp/a2dp_vendor_aptx.cc index 35a1621dc..fc4d610ab 100644 --- a/stack/a2dp/a2dp_vendor_aptx.cc +++ b/stack/a2dp/a2dp_vendor_aptx.cc @@ -76,8 +76,8 @@ static const tA2DP_ENCODER_INTERFACE a2dp_encoder_interface_aptx = { a2dp_vendor_aptx_feeding_flush, a2dp_vendor_aptx_get_encoder_interval_ms, a2dp_vendor_aptx_send_frames, - nullptr, // set_transmit_queue_length - a2dp_vendor_aptx_debug_codec_dump}; + nullptr // set_transmit_queue_length +}; UNUSED_ATTR static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAptx( const tA2DP_APTX_CIE* p_cap, const uint8_t* p_codec_info, diff --git a/stack/a2dp/a2dp_vendor_aptx_encoder.cc b/stack/a2dp/a2dp_vendor_aptx_encoder.cc index 51213e11e..4c8554df3 100644 --- a/stack/a2dp/a2dp_vendor_aptx_encoder.cc +++ b/stack/a2dp/a2dp_vendor_aptx_encoder.cc @@ -475,25 +475,29 @@ static size_t aptx_encode_16bit(tAPTX_FRAMING_PARAMS* framing_params, return pcm_bytes_encoded; } -void a2dp_vendor_aptx_debug_codec_dump(int fd) { +period_ms_t A2dpCodecConfigAptx::encoderIntervalMs() const { + return a2dp_vendor_aptx_get_encoder_interval_ms(); +} + +void A2dpCodecConfigAptx::debug_codec_dump(int fd) { a2dp_aptx_encoder_stats_t* stats = &a2dp_aptx_encoder_cb.stats; - dprintf(fd, "\nA2DP aptX State:\n"); + A2dpCodecConfig::debug_codec_dump(fd); dprintf(fd, - " Packets expected/dropped : %zu / " + " Packet counts (expected/dropped) : %zu / " "%zu\n", stats->media_read_total_expected_packets, stats->media_read_total_dropped_packets); dprintf(fd, - " PCM reads count expected/actual : %zu / " + " PCM read counts (expected/actual) : %zu / " "%zu\n", stats->media_read_total_expected_reads_count, stats->media_read_total_actual_reads_count); dprintf(fd, - " PCM read bytes expected/actual : %zu / " + " PCM read bytes (expected/actual) : %zu / " "%zu\n", stats->media_read_total_expected_read_bytes, stats->media_read_total_actual_read_bytes); diff --git a/stack/a2dp/a2dp_vendor_aptx_hd.cc b/stack/a2dp/a2dp_vendor_aptx_hd.cc index 449e84e45..a5d9d5fe1 100644 --- a/stack/a2dp/a2dp_vendor_aptx_hd.cc +++ b/stack/a2dp/a2dp_vendor_aptx_hd.cc @@ -83,8 +83,8 @@ static const tA2DP_ENCODER_INTERFACE a2dp_encoder_interface_aptx_hd = { a2dp_vendor_aptx_hd_feeding_flush, a2dp_vendor_aptx_hd_get_encoder_interval_ms, a2dp_vendor_aptx_hd_send_frames, - nullptr, // set_transmit_queue_length - a2dp_vendor_aptx_hd_debug_codec_dump}; + nullptr // set_transmit_queue_length +}; UNUSED_ATTR static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAptxHd( const tA2DP_APTX_HD_CIE* p_cap, const uint8_t* p_codec_info, diff --git a/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc b/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc index 863ccb9ee..d35d872bb 100644 --- a/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc +++ b/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc @@ -470,25 +470,29 @@ static size_t aptx_hd_encode_24bit(tAPTX_HD_FRAMING_PARAMS* framing_params, return pcm_bytes_encoded; } -void a2dp_vendor_aptx_hd_debug_codec_dump(int fd) { +period_ms_t A2dpCodecConfigAptxHd::encoderIntervalMs() const { + return a2dp_vendor_aptx_hd_get_encoder_interval_ms(); +} + +void A2dpCodecConfigAptxHd::debug_codec_dump(int fd) { a2dp_aptx_hd_encoder_stats_t* stats = &a2dp_aptx_hd_encoder_cb.stats; - dprintf(fd, "\nA2DP aptX-HD State:\n"); + A2dpCodecConfig::debug_codec_dump(fd); dprintf(fd, - " Packets expected/dropped : %zu / " + " Packet counts (expected/dropped) : %zu / " "%zu\n", stats->media_read_total_expected_packets, stats->media_read_total_dropped_packets); dprintf(fd, - " PCM reads count expected/actual : %zu / " + " PCM read counts (expected/actual) : %zu / " "%zu\n", stats->media_read_total_expected_reads_count, stats->media_read_total_actual_reads_count); dprintf(fd, - " PCM read bytes expected/actual : %zu / " + " PCM read bytes (expected/actual) : %zu / " "%zu\n", stats->media_read_total_expected_read_bytes, stats->media_read_total_actual_read_bytes); diff --git a/stack/a2dp/a2dp_vendor_ldac.cc b/stack/a2dp/a2dp_vendor_ldac.cc index 6e7397ee6..912f2ae4d 100644 --- a/stack/a2dp/a2dp_vendor_ldac.cc +++ b/stack/a2dp/a2dp_vendor_ldac.cc @@ -76,8 +76,7 @@ static const tA2DP_ENCODER_INTERFACE a2dp_encoder_interface_ldac = { a2dp_vendor_ldac_feeding_flush, a2dp_vendor_ldac_get_encoder_interval_ms, a2dp_vendor_ldac_send_frames, - a2dp_vendor_ldac_set_transmit_queue_length, - a2dp_vendor_ldac_debug_codec_dump}; + a2dp_vendor_ldac_set_transmit_queue_length}; UNUSED_ATTR static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityLdac( const tA2DP_LDAC_CIE* p_cap, const uint8_t* p_codec_info, diff --git a/stack/a2dp/a2dp_vendor_ldac_encoder.cc b/stack/a2dp/a2dp_vendor_ldac_encoder.cc index b36e59c40..9011118e5 100644 --- a/stack/a2dp/a2dp_vendor_ldac_encoder.cc +++ b/stack/a2dp/a2dp_vendor_ldac_encoder.cc @@ -98,12 +98,6 @@ static tLDAC_ALTER_EQMID_PRIORITY ldac_alter_eqmid_priority_func; static tLDAC_GET_EQMID ldac_get_eqmid_func; static tLDAC_GET_ERROR_CODE ldac_get_error_code_func; -#define STATS_UPDATE_MAX(current_value_storage, new_value) \ - do { \ - if ((new_value) > (current_value_storage)) \ - (current_value_storage) = (new_value); \ - } while (0) - // A2DP LDAC encoder interval in milliseconds #define A2DP_LDAC_ENCODER_INTERVAL_MS 20 #define A2DP_LDAC_MEDIA_BYTES_PER_FRAME 128 @@ -613,17 +607,19 @@ static void a2dp_ldac_encode_frames(uint8_t nb_frame) { int32_t encode_count = 0; int32_t out_frames = 0; int written = 0; + while (nb_frame) { BT_HDR* p_buf = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE); - - /* Init buffer */ p_buf->offset = A2DP_LDAC_OFFSET; p_buf->len = 0; p_buf->layer_specific = 0; + a2dp_ldac_encoder_cb.stats.media_read_total_expected_packets++; count = 0; do { - /* Read PCM data */ + // + // Read the PCM data and encode it + // if (a2dp_ldac_read_feeding(read_buffer)) { uint8_t* packet = (uint8_t*)(p_buf + 1) + p_buf->offset + p_buf->len; if (a2dp_ldac_encoder_cb.ldac_handle == NULL) { @@ -674,6 +670,7 @@ static void a2dp_ldac_encode_frames(uint8_t nb_frame) { remain_nb_frame = nb_frame; if (!a2dp_ldac_encoder_cb.enqueue_callback(p_buf, done_nb_frame)) return; } else { + a2dp_ldac_encoder_cb.stats.media_read_total_dropped_packets++; osi_free(p_buf); } } @@ -684,9 +681,13 @@ static bool a2dp_ldac_read_feeding(uint8_t* read_buffer) { a2dp_ldac_encoder_cb.feeding_params.channel_count * a2dp_ldac_encoder_cb.feeding_params.bits_per_sample / 8; + a2dp_ldac_encoder_cb.stats.media_read_total_expected_reads_count++; + a2dp_ldac_encoder_cb.stats.media_read_total_expected_read_bytes += read_size; + /* Read Data from UIPC channel */ uint32_t nb_byte_read = a2dp_ldac_encoder_cb.read_callback(read_buffer, read_size); + a2dp_ldac_encoder_cb.stats.media_read_total_actual_read_bytes += nb_byte_read; if (nb_byte_read < read_size) { if (nb_byte_read == 0) return false; @@ -695,6 +696,8 @@ static bool a2dp_ldac_read_feeding(uint8_t* read_buffer) { memset(((uint8_t*)read_buffer) + nb_byte_read, 0, read_size - nb_byte_read); nb_byte_read = read_size; } + a2dp_ldac_encoder_cb.stats.media_read_total_actual_reads_count++; + return true; } @@ -717,35 +720,40 @@ void a2dp_vendor_ldac_set_transmit_queue_length(size_t transmit_queue_length) { a2dp_ldac_encoder_cb.TxQueueLength = transmit_queue_length; } -void a2dp_vendor_ldac_debug_codec_dump(int fd) { +period_ms_t A2dpCodecConfigLdac::encoderIntervalMs() const { + return a2dp_vendor_ldac_get_encoder_interval_ms(); +} + +void A2dpCodecConfigLdac::debug_codec_dump(int fd) { a2dp_ldac_encoder_stats_t* stats = &a2dp_ldac_encoder_cb.stats; tA2DP_LDAC_ENCODER_PARAMS* p_encoder_params = &a2dp_ldac_encoder_cb.ldac_encoder_params; - dprintf(fd, "\nA2DP LDAC State:\n"); + A2dpCodecConfig::debug_codec_dump(fd); dprintf(fd, - " Packets expected/dropped : %zu / " + " Packet counts (expected/dropped) : %zu / " "%zu\n", stats->media_read_total_expected_packets, stats->media_read_total_dropped_packets); dprintf(fd, - " PCM reads count expected/actual : %zu / " + " PCM read counts (expected/actual) : %zu / " "%zu\n", stats->media_read_total_expected_reads_count, stats->media_read_total_actual_reads_count); dprintf(fd, - " PCM read bytes expected/actual : %zu / " + " PCM read bytes (expected/actual) : %zu / " "%zu\n", stats->media_read_total_expected_read_bytes, stats->media_read_total_actual_read_bytes); dprintf( - fd, "\nA2DP LDAC current quality mode: %s\n", + fd, " LDAC quality mode : %s\n", quality_mode_index_to_name(p_encoder_params->quality_mode_index).c_str()); - dprintf(fd, "\nA2DP LDAC saved transmit queue length: %zu\n", + dprintf(fd, + " LDAC saved transmit queue length : %zu\n", a2dp_ldac_encoder_cb.TxQueueLength); } diff --git a/stack/include/a2dp_aac.h b/stack/include/a2dp_aac.h index ba0a80d3e..8ddd185c8 100644 --- a/stack/include/a2dp_aac.h +++ b/stack/include/a2dp_aac.h @@ -31,6 +31,7 @@ class A2dpCodecConfigAac : public A2dpCodecConfig { virtual ~A2dpCodecConfigAac(); bool init() override; + period_ms_t encoderIntervalMs() const override; bool setCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability, uint8_t* p_result_codec_config) override; @@ -39,6 +40,8 @@ class A2dpCodecConfigAac : public A2dpCodecConfig { 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; }; // Checks whether the codec capabilities contain a valid A2DP AAC Source diff --git a/stack/include/a2dp_aac_encoder.h b/stack/include/a2dp_aac_encoder.h index d07a9a526..e72b18cc4 100644 --- a/stack/include/a2dp_aac_encoder.h +++ b/stack/include/a2dp_aac_encoder.h @@ -57,9 +57,4 @@ period_ms_t a2dp_aac_get_encoder_interval_ms(void); // |timestamp_us| is the current timestamp (in microseconds). void a2dp_aac_send_frames(uint64_t timestamp_us); -// Dump AAC codec-related statistics. -// |fd| is the file descriptor to use to dump the statistics information -// in user-friendly test format. -void a2dp_aac_debug_codec_dump(int fd); - #endif // A2DP_AAC_ENCODER_H diff --git a/stack/include/a2dp_codec_api.h b/stack/include/a2dp_codec_api.h index cb28466ef..b25dcbc12 100644 --- a/stack/include/a2dp_codec_api.h +++ b/stack/include/a2dp_codec_api.h @@ -68,7 +68,7 @@ class A2dpCodecConfig { btav_a2dp_codec_priority_t codecPriority() const { return codec_priority_; } // Copies out the current OTA codec config to |p_codec_info|. - // Returns true if the current codec config is valied and copied, + // Returns true if the current codec config is valid and copied, // otherwise false. bool copyOutOtaCodecConfig(uint8_t* p_codec_info); @@ -187,6 +187,46 @@ class A2dpCodecConfig { // Checks whether the internal state is valid virtual bool isValid() const; + // Returns the encoder's periodic interval (in milliseconds). + virtual period_ms_t encoderIntervalMs() const = 0; + + // Checks whether the A2DP Codec Configuration is valid. + // Returns true if A2DP Codec Configuration stored in |codec_config| + // is valid, otherwise false. + static bool codecConfigIsValid(const btav_a2dp_codec_config_t& codec_config); + + // Gets the string representation of A2DP Codec Configuration. + // Returns the string representation of A2DP Codec Configuration stored + // in |codec_config|. The format is: + // "Rate=44100|48000 Bits=16|24 Mode=MONO|STEREO" + static std::string codecConfig2Str( + const btav_a2dp_codec_config_t& codec_config); + + // Gets the string representation of A2DP Codec Sample Rate. + // Returns the string representation of A2DP Codec Sample Rate stored + // in |codec_sample_rate|. If there are multiple values stored in + // |codec_sample_rate|, the return string format is "rate1|rate2|rate3". + static std::string codecSampleRate2Str( + btav_a2dp_codec_sample_rate_t codec_sample_rate); + + // Gets the string representation of A2DP Codec Bits Per Sample. + // Returns the string representation of A2DP Codec Bits Per Sample stored + // in |codec_bits_per_sample|. If there are multiple values stored in + // |codec_bits_per_sample|, the return string format is "bits1|bits2|bits3". + static std::string codecBitsPerSample2Str( + btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample); + + // Gets the string representation of A2DP Codec Channel Mode. + // Returns the string representation of A2DP Channel Mode stored + // in |codec_channel_mode|. If there are multiple values stored in + // |codec_channel_mode|, the return string format is "mode1|mode2|mode3". + static std::string codecChannelMode2Str( + btav_a2dp_codec_channel_mode_t codec_channel_mode); + + // Dumps codec-related information. + // The information is written in user-friendly form to file descriptor |fd|. + virtual void debug_codec_dump(int fd); + std::recursive_mutex codec_mutex_; const btav_a2dp_codec_index_t codec_index_; // The unique codec index const std::string name_; // The codec name @@ -356,6 +396,10 @@ class A2dpCodecs { std::vector* p_codecs_local_capabilities, std::vector* p_codecs_selectable_capabilities); + // Dumps codec-related information. + // The information is written in user-friendly form to file descriptor |fd|. + void debug_codec_dump(int fd); + private: struct CompareBtBdaddr : public std::binary_function { @@ -437,11 +481,6 @@ typedef struct { // Set transmit queue length for the A2DP encoder. void (*set_transmit_queue_length)(size_t transmit_queue_length); - - // Dump codec-related statistics. - // |fd| is the file descriptor to use to dump the statistics information - // in user-friendly test format. - void (*debug_codec_dump)(int fd); } tA2DP_ENCODER_INTERFACE; // Gets the A2DP codec type. diff --git a/stack/include/a2dp_sbc.h b/stack/include/a2dp_sbc.h index b348746d4..6077cd581 100644 --- a/stack/include/a2dp_sbc.h +++ b/stack/include/a2dp_sbc.h @@ -31,6 +31,7 @@ class A2dpCodecConfigSbc : public A2dpCodecConfig { virtual ~A2dpCodecConfigSbc(); bool init() override; + period_ms_t encoderIntervalMs() const override; bool setCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability, uint8_t* p_result_codec_config) override; @@ -39,6 +40,8 @@ class A2dpCodecConfigSbc : public A2dpCodecConfig { 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; }; class A2dpCodecConfigSbcSink : public A2dpCodecConfig { @@ -47,6 +50,7 @@ class A2dpCodecConfigSbcSink : public A2dpCodecConfig { virtual ~A2dpCodecConfigSbcSink(); bool init() override; + period_ms_t encoderIntervalMs() const override; bool setCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability, uint8_t* p_result_codec_config) override; diff --git a/stack/include/a2dp_sbc_encoder.h b/stack/include/a2dp_sbc_encoder.h index ffbfdcaf3..6ff1cf7d3 100644 --- a/stack/include/a2dp_sbc_encoder.h +++ b/stack/include/a2dp_sbc_encoder.h @@ -60,9 +60,4 @@ period_ms_t a2dp_sbc_get_encoder_interval_ms(void); // |timestamp_us| is the current timestamp (in microseconds). void a2dp_sbc_send_frames(uint64_t timestamp_us); -// Dump SBC codec-related statistics. -// |fd| is the file descriptor to use to dump the statistics information -// in user-friendly test format. -void a2dp_sbc_debug_codec_dump(int fd); - #endif // A2DP_SBC_ENCODER_H diff --git a/stack/include/a2dp_vendor_aptx.h b/stack/include/a2dp_vendor_aptx.h index 1e49a1598..f17feb43f 100644 --- a/stack/include/a2dp_vendor_aptx.h +++ b/stack/include/a2dp_vendor_aptx.h @@ -31,6 +31,7 @@ class A2dpCodecConfigAptx : public A2dpCodecConfig { virtual ~A2dpCodecConfigAptx(); bool init() override; + period_ms_t encoderIntervalMs() const override; bool setCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability, uint8_t* p_result_codec_config) override; @@ -39,6 +40,8 @@ class A2dpCodecConfigAptx : public A2dpCodecConfig { 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; }; // Checks whether the codec capabilities contain a valid A2DP aptX Source diff --git a/stack/include/a2dp_vendor_aptx_encoder.h b/stack/include/a2dp_vendor_aptx_encoder.h index 52b8edcde..7a67307c2 100644 --- a/stack/include/a2dp_vendor_aptx_encoder.h +++ b/stack/include/a2dp_vendor_aptx_encoder.h @@ -58,9 +58,4 @@ period_ms_t a2dp_vendor_aptx_get_encoder_interval_ms(void); // |timestamp_us| is the current timestamp (in microseconds). void a2dp_vendor_aptx_send_frames(uint64_t timestamp_us); -// Dump aptX codec-related statistics. -// |fd| is the file descriptor to use to dump the statistics information -// in user-friendly test format. -void a2dp_vendor_aptx_debug_codec_dump(int fd); - #endif // A2DP_VENDOR_APTX_ENCODER_H diff --git a/stack/include/a2dp_vendor_aptx_hd.h b/stack/include/a2dp_vendor_aptx_hd.h index 8016a7894..8a4df8c5a 100644 --- a/stack/include/a2dp_vendor_aptx_hd.h +++ b/stack/include/a2dp_vendor_aptx_hd.h @@ -31,6 +31,7 @@ class A2dpCodecConfigAptxHd : public A2dpCodecConfig { virtual ~A2dpCodecConfigAptxHd(); bool init() override; + period_ms_t encoderIntervalMs() const override; bool setCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability, uint8_t* p_result_codec_config) override; @@ -39,6 +40,8 @@ class A2dpCodecConfigAptxHd : public A2dpCodecConfig { 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; }; // Checks whether the codec capabilities contain a valid A2DP aptX-HD Source diff --git a/stack/include/a2dp_vendor_aptx_hd_encoder.h b/stack/include/a2dp_vendor_aptx_hd_encoder.h index c7708f363..b662e8e79 100644 --- a/stack/include/a2dp_vendor_aptx_hd_encoder.h +++ b/stack/include/a2dp_vendor_aptx_hd_encoder.h @@ -58,9 +58,4 @@ period_ms_t a2dp_vendor_aptx_hd_get_encoder_interval_ms(void); // |timestamp_us| is the current timestamp (in microseconds). void a2dp_vendor_aptx_hd_send_frames(uint64_t timestamp_us); -// Dump aptX-HD codec-related statistics. -// |fd| is the file descriptor to use to dump the statistics information -// in user-friendly test format. -void a2dp_vendor_aptx_hd_debug_codec_dump(int fd); - #endif // A2DP_VENDOR_APTX_HD_ENCODER_H diff --git a/stack/include/a2dp_vendor_ldac.h b/stack/include/a2dp_vendor_ldac.h index 471e6b4c1..813f10516 100644 --- a/stack/include/a2dp_vendor_ldac.h +++ b/stack/include/a2dp_vendor_ldac.h @@ -31,6 +31,7 @@ class A2dpCodecConfigLdac : public A2dpCodecConfig { virtual ~A2dpCodecConfigLdac(); bool init() override; + period_ms_t encoderIntervalMs() const override; bool setCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability, uint8_t* p_result_codec_config) override; @@ -39,6 +40,8 @@ class A2dpCodecConfigLdac : public A2dpCodecConfig { 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; }; // Checks whether the codec capabilities contain a valid A2DP LDAC Source diff --git a/stack/include/a2dp_vendor_ldac_encoder.h b/stack/include/a2dp_vendor_ldac_encoder.h index 33984a80f..45694f01c 100644 --- a/stack/include/a2dp_vendor_ldac_encoder.h +++ b/stack/include/a2dp_vendor_ldac_encoder.h @@ -61,9 +61,4 @@ void a2dp_vendor_ldac_send_frames(uint64_t timestamp_us); // Set transmit queue length for the A2DP LDAC ABR(Adaptive Bit Rate) mechanism. void a2dp_vendor_ldac_set_transmit_queue_length(size_t transmit_queue_length); -// Dump LDAC codec-related statistics. -// |fd| is the file descriptor to use to dump the statistics information -// in user-friendly test format. -void a2dp_vendor_ldac_debug_codec_dump(int fd); - #endif // A2DP_VENDOR_LDAC_ENCODER_H -- 2.11.0