@@ -118,9 +118,24 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
118118
119119 mDrainAudioQueuePending = false ;
120120
121- onDrainAudioQueue ();
122-
123- postDrainAudioQueue ();
121+ if (onDrainAudioQueue ()) {
122+ uint32_t numFramesPlayed;
123+ CHECK_EQ (mAudioSink ->getPosition (&numFramesPlayed),
124+ (status_t )OK);
125+
126+ uint32_t numFramesPendingPlayout =
127+ mNumFramesWritten - numFramesPlayed;
128+
129+ // This is how long the audio sink will have data to
130+ // play back.
131+ int64_t delayUs =
132+ mAudioSink ->msecsPerFrame ()
133+ * numFramesPendingPlayout * 1000ll ;
134+
135+ // Let's give it more data after about half that time
136+ // has elapsed.
137+ postDrainAudioQueue (delayUs / 2 );
138+ }
124139 break ;
125140 }
126141
@@ -182,7 +197,7 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
182197 }
183198}
184199
185- void NuPlayer::Renderer::postDrainAudioQueue () {
200+ void NuPlayer::Renderer::postDrainAudioQueue (int64_t delayUs ) {
186201 if (mDrainAudioQueuePending || mSyncQueues || mPaused ) {
187202 return ;
188203 }
@@ -194,19 +209,33 @@ void NuPlayer::Renderer::postDrainAudioQueue() {
194209 mDrainAudioQueuePending = true ;
195210 sp<AMessage> msg = new AMessage (kWhatDrainAudioQueue , id ());
196211 msg->setInt32 (" generation" , mAudioQueueGeneration );
197- msg->post ();
212+ msg->post (delayUs );
198213}
199214
200215void NuPlayer::Renderer::signalAudioSinkChanged () {
201216 (new AMessage (kWhatAudioSinkChanged , id ()))->post ();
202217}
203218
204- void NuPlayer::Renderer::onDrainAudioQueue () {
205- for (;;) {
206- if (mAudioQueue .empty ()) {
207- break ;
208- }
219+ bool NuPlayer::Renderer::onDrainAudioQueue () {
220+ uint32_t numFramesPlayed;
221+ CHECK_EQ (mAudioSink ->getPosition (&numFramesPlayed), (status_t )OK);
222+
223+ ssize_t numFramesAvailableToWrite =
224+ mAudioSink ->frameCount () - (mNumFramesWritten - numFramesPlayed);
225+
226+ #if 0
227+ if (numFramesAvailableToWrite == mAudioSink->frameCount()) {
228+ LOGI("audio sink underrun");
229+ } else {
230+ LOGV("audio queue has %d frames left to play",
231+ mAudioSink->frameCount() - numFramesAvailableToWrite);
232+ }
233+ #endif
209234
235+ size_t numBytesAvailableToWrite =
236+ numFramesAvailableToWrite * mAudioSink ->frameSize ();
237+
238+ while (numBytesAvailableToWrite > 0 && !mAudioQueue .empty ()) {
210239 QueueEntry *entry = &*mAudioQueue .begin ();
211240
212241 if (entry->mBuffer == NULL ) {
@@ -216,20 +245,7 @@ void NuPlayer::Renderer::onDrainAudioQueue() {
216245
217246 mAudioQueue .erase (mAudioQueue .begin ());
218247 entry = NULL ;
219- return ;
220- }
221-
222- uint32_t numFramesPlayed;
223- CHECK_EQ (mAudioSink ->getPosition (&numFramesPlayed), (status_t )OK);
224-
225- ssize_t numFramesAvailableToWrite =
226- mAudioSink ->frameCount () - (mNumFramesWritten - numFramesPlayed);
227-
228- size_t numBytesAvailableToWrite =
229- numFramesAvailableToWrite * mAudioSink ->frameSize ();
230-
231- if (numBytesAvailableToWrite == 0 ) {
232- break ;
248+ return false ;
233249 }
234250
235251 if (entry->mOffset == 0 ) {
@@ -274,10 +290,14 @@ void NuPlayer::Renderer::onDrainAudioQueue() {
274290 entry = NULL ;
275291 }
276292
277- mNumFramesWritten += copy / mAudioSink ->frameSize ();
293+ numBytesAvailableToWrite -= copy;
294+ size_t copiedFrames = copy / mAudioSink ->frameSize ();
295+ mNumFramesWritten += copiedFrames;
278296 }
279297
280298 notifyPosition ();
299+
300+ return !mAudioQueue .empty ();
281301}
282302
283303void NuPlayer::Renderer::postDrainVideoQueue () {
@@ -344,7 +364,14 @@ void NuPlayer::Renderer::onDrainVideoQueue() {
344364 int64_t mediaTimeUs;
345365 CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
346366
347- LOGI("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
367+ int64_t realTimeUs = mediaTimeUs - mAnchorTimeMediaUs + mAnchorTimeRealUs;
368+ int64_t lateByUs = ALooper::GetNowUs() - realTimeUs;
369+
370+ if (lateByUs > 40000) {
371+ LOGI("video late by %lld us (%.2f secs)", lateByUs, lateByUs / 1E6);
372+ } else {
373+ LOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
374+ }
348375#endif
349376
350377 entry->mNotifyConsumed ->setInt32 (" render" , true );
0 commit comments