From bd1e80cba6360af5c6f8e4d9eeba28ae8fa1f998 Mon Sep 17 00:00:00 2001 From: Benjamin Chen Date: Tue, 5 May 2015 16:00:14 +0800 Subject: [PATCH] Bug 1104643 - Interpolate the audio clock by system clock if the qudio clock is not going forward. r=padenot --- media/libcubeb/src/cubeb_opensl.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/media/libcubeb/src/cubeb_opensl.c b/media/libcubeb/src/cubeb_opensl.c index 7f166149997..c90e68f30a6 100644 --- a/media/libcubeb/src/cubeb_opensl.c +++ b/media/libcubeb/src/cubeb_opensl.c @@ -11,6 +11,7 @@ #include #include #include +#include #if defined(__ANDROID__) #include #include "android/sles_definitions.h" @@ -70,6 +71,9 @@ struct cubeb_stream { unsigned int inputrate; unsigned int outputrate; unsigned int latency; + int64_t lastPosition; + int64_t lastPositionTimeStamp; + int64_t lastCompensativePosition; }; static void @@ -511,6 +515,9 @@ opensl_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name stm->latency = latency; stm->stream_type = stream_params.stream_type; stm->framesize = stream_params.channels * sizeof(int16_t); + stm->lastPosition = -1; + stm->lastPositionTimeStamp = 0; + stm->lastCompensativePosition = -1; int r = pthread_mutex_init(&stm->mutex, NULL); assert(r == 0); @@ -697,11 +704,22 @@ opensl_stream_get_position(cubeb_stream * stm, uint64_t * position) SLresult res; int r; uint32_t mixer_latency; + uint32_t compensation_msec = 0; res = (*stm->play)->GetPosition(stm->play, &msec); if (res != SL_RESULT_SUCCESS) return CUBEB_ERROR; + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + if(stm->lastPosition == msec || msec < stm->lastCompensativePosition) { + compensation_msec = + (t.tv_sec*1000000000LL + t.tv_nsec - stm->lastPositionTimeStamp) / 1000000; + } else { + stm->lastPositionTimeStamp = t.tv_sec*1000000000LL + t.tv_nsec; + stm->lastPosition = msec; + } + samplerate = stm->inputrate; r = stm->context->get_output_latency(&mixer_latency, stm->stream_type); @@ -715,12 +733,14 @@ opensl_stream_get_position(cubeb_stream * stm, uint64_t * position) assert(maximum_position >= 0); if (msec > mixer_latency) { - int64_t unadjusted_position = samplerate * (msec - mixer_latency) / 1000; + int64_t unadjusted_position = + samplerate * (msec - mixer_latency + compensation_msec) / 1000; *position = unadjusted_position < maximum_position ? unadjusted_position : maximum_position; } else { *position = 0; } + stm->lastCompensativePosition = *position; return CUBEB_OK; }