Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5972fa9 authored by Aniket Kumar Lata's avatar Aniket Kumar Lata Committed by Gerrit - the friendly Code Review server
Browse files

hal: AV sync latency correction for split A2dp

Audio lagging video for split A2DP. Encoder latencies were not
considered for SBC/APTX/APTXHD/AAC formats taking deep buffer,
PCM offload, low latency paths. A latency of 200-300ms observed
across formats. Our current solution changes the out_get_latency()
function in primary HAL to update latency based on BT codec formats.

CRs-Fixed: 2004199
Change-Id: I8f19018054e3945d618ba6bcfef5d28e4fbab716
parent 09ecbd9b
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -824,4 +824,51 @@ void audio_extn_a2dp_init (void *adev)
  a2dp.is_handoff_in_progress = false;
  update_offload_codec_capabilities();
}

uint32_t audio_extn_a2dp_get_encoder_latency()
{
    void *codec_info = NULL;
    uint8_t multi_cast = 0, num_dev = 1;
    audio_format_t codec_type = AUDIO_FORMAT_INVALID;
    uint32_t latency = 0;
    int avsync_runtime_prop = 0;
    int sbc_offset = 0, aptx_offset = 0, aptxhd_offset = 0, aac_offset = 0;
    char value[PROPERTY_VALUE_MAX];

    if (!a2dp.audio_get_codec_config) {
        ALOGE(" a2dp handle is not identified");
        return latency;
    }
    codec_info = a2dp.audio_get_codec_config(&multi_cast, &num_dev,
                               &codec_type);

    memset(value, '\0', sizeof(char)*PROPERTY_VALUE_MAX);
    avsync_runtime_prop = property_get("audio.a2dp.codec.latency", value, NULL);
    if (avsync_runtime_prop > 0) {
        if (sscanf(value, "%d/%d/%d/%d",
                  &sbc_offset, &aptx_offset, &aptxhd_offset, &aac_offset) != 4) {
            ALOGI("Failed to parse avsync offset params from '%s'.", value);
            avsync_runtime_prop = 0;
        }
    }

    switch(codec_type) {
        case AUDIO_FORMAT_SBC:
            latency = (avsync_runtime_prop > 0) ? sbc_offset : 150;
            break;
        case AUDIO_FORMAT_APTX:
            latency = (avsync_runtime_prop > 0) ? aptx_offset : 200;
            break;
        case AUDIO_FORMAT_APTX_HD:
            latency = (avsync_runtime_prop > 0) ? aptxhd_offset : 200;
            break;
        case AUDIO_FORMAT_AAC:
            latency = (avsync_runtime_prop > 0) ? aac_offset : 250;
            break;
        default:
            latency = 200;
            break;
    }
    return latency;
}
#endif // SPLIT_A2DP_ENABLED
+2 −0
Original line number Diff line number Diff line
@@ -205,6 +205,7 @@ bool audio_extn_usb_is_capture_supported();
#define audio_extn_a2dp_is_force_device_switch()         (0)
#define audio_extn_a2dp_set_handoff_mode(is_on)          (0)
#define audio_extn_a2dp_get_apptype_params(sample_rate,bit_width)    (0)
#define audio_extn_a2dp_get_encoder_latency()            (0)

#else
void audio_extn_a2dp_init(void *adev);
@@ -215,6 +216,7 @@ bool audio_extn_a2dp_is_force_device_switch();
void audio_extn_a2dp_set_handoff_mode(bool is_on);
void audio_extn_a2dp_get_apptype_params(uint32_t *sample_rate,
                                        uint32_t *bit_width);
uint32_t audio_extn_a2dp_get_encoder_latency();

#endif

+4 −0
Original line number Diff line number Diff line
@@ -2895,6 +2895,10 @@ static uint32_t out_get_latency(const struct audio_stream_out *stream)
           (out->config.rate);
    }

    if ((AUDIO_DEVICE_OUT_BLUETOOTH_A2DP == out->devices) &&
            !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))
        latency += audio_extn_a2dp_get_encoder_latency();

    ALOGV("%s: Latency %d", __func__, latency);
    return latency;
}