void NuPlayer::Renderer::onQueueEOS(const sp<AMessage> &msg) { int32_t audio; CHECK(msg->findInt32("audio", &audio)); if (dropBufferWhileFlushing(audio, msg)) { return; } int32_t finalResult; CHECK(msg->findInt32("finalResult", &finalResult)); QueueEntry entry; entry.mOffset = 0; entry.mFinalResult = finalResult; if (audio) { if (mAudioQueue.empty() && mSyncQueues) { syncQueuesDone(); } mAudioQueue.push_back(entry); postDrainAudioQueue(); } else { if (mVideoQueue.empty() && mSyncQueues) { syncQueuesDone(); } mVideoQueue.push_back(entry); postDrainVideoQueue(); } }
void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) { int32_t audio; CHECK(msg->findInt32("audio", &audio)); // If we're currently syncing the queues, i.e. dropping audio while // aligning the first audio/video buffer times and only one of the // two queues has data, we may starve that queue by not requesting // more buffers from the decoder. If the other source then encounters // a discontinuity that leads to flushing, we'll never find the // corresponding discontinuity on the other queue. // Therefore we'll stop syncing the queues if at least one of them // is flushed. syncQueuesDone(); if (audio) { flushQueue(&mAudioQueue); Mutex::Autolock autoLock(mFlushLock); mFlushingAudio = false; mDrainAudioQueuePending = false; ++mAudioQueueGeneration; } else { flushQueue(&mVideoQueue); Mutex::Autolock autoLock(mFlushLock); mFlushingVideo = false; mDrainVideoQueuePending = false; ++mVideoQueueGeneration; } notifyFlushComplete(audio); }
void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) { int32_t audio; CHECK(msg->findInt32("audio", &audio)); // If we're currently syncing the queues, i.e. dropping audio while // aligning the first audio/video buffer times and only one of the // two queues has data, we may starve that queue by not requesting // more buffers from the decoder. If the other source then encounters // a discontinuity that leads to flushing, we'll never find the // corresponding discontinuity on the other queue. // Therefore we'll stop syncing the queues if at least one of them // is flushed. syncQueuesDone(); ALOGV("flushing %s", audio ? "audio" : "video"); if (audio) { #ifndef ANDROID_DEFAULT_CODE //@debug dumpQueue(&mAudioQueue, audio); mHasAudio = false; #endif flushQueue(&mAudioQueue); #ifndef ANDROID_DEFAULT_CODE mAudioSink->pause(); mAudioSink->flush(); mNumFramesWritten = 0; mAudioSink->start(); #endif Mutex::Autolock autoLock(mFlushLock); mFlushingAudio = false; mDrainAudioQueuePending = false; ++mAudioQueueGeneration; prepareForMediaRenderingStart(); } else { #ifndef ANDROID_DEFAULT_CODE //@debug dumpQueue(&mVideoQueue, audio); mHasVideo = false; #endif flushQueue(&mVideoQueue); Mutex::Autolock autoLock(mFlushLock); mFlushingVideo = false; mDrainVideoQueuePending = false; ++mVideoQueueGeneration; prepareForMediaRenderingStart(); } notifyFlushComplete(audio); }
void DashPlayer::Renderer::queueEOS(bool audio, status_t finalResult) { CHECK_NE(finalResult, (status_t)OK); if(mSyncQueues) syncQueuesDone(); sp<AMessage> msg = new AMessage(kWhatQueueEOS, id()); msg->setInt32("audio", static_cast<int32_t>(audio)); msg->setInt32("finalResult", finalResult); msg->post(); }
void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) { int32_t audio; CHECK(msg->findInt32("audio", &audio)); if (audio) { mHasAudio = true; } else { mHasVideo = true; } if (dropBufferWhileFlushing(audio, msg)) { return; } sp<RefBase> obj; CHECK(msg->findObject("buffer", &obj)); sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get()); sp<AMessage> notifyConsumed; CHECK(msg->findMessage("notifyConsumed", ¬ifyConsumed)); QueueEntry entry; entry.mBuffer = buffer; entry.mNotifyConsumed = notifyConsumed; entry.mOffset = 0; entry.mFinalResult = OK; if (audio) { mAudioQueue.push_back(entry); postDrainAudioQueue(); } else { mVideoQueue.push_back(entry); postDrainVideoQueue(); } if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) { return; } sp<ABuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer; sp<ABuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer; if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) { // EOS signalled on either queue. syncQueuesDone(); return; } int64_t firstAudioTimeUs; int64_t firstVideoTimeUs; CHECK(firstAudioBuffer->meta() ->findInt64("timeUs", &firstAudioTimeUs)); CHECK(firstVideoBuffer->meta() ->findInt64("timeUs", &firstVideoTimeUs)); int64_t diff = firstVideoTimeUs - firstAudioTimeUs; ALOGV("queueDiff = %.2f secs", diff / 1E6); if (diff > 100000ll) { // Audio data starts More than 0.1 secs before video. // Drop some audio. (*mAudioQueue.begin()).mNotifyConsumed->post(); mAudioQueue.erase(mAudioQueue.begin()); return; } syncQueuesDone(); }
void DashPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) { int32_t audio; CHECK(msg->findInt32("audio", &audio)); if (audio) { mHasAudio = true; } else { mHasVideo = true; } if (dropBufferWhileFlushing(audio, msg)) { return; } sp<ABuffer> buffer; CHECK(msg->findBuffer("buffer", &buffer)); sp<AMessage> notifyConsumed; CHECK(msg->findMessage("notifyConsumed", ¬ifyConsumed)); QueueEntry entry; entry.mBuffer = buffer; entry.mNotifyConsumed = notifyConsumed; entry.mOffset = 0; entry.mFinalResult = OK; if (audio) { mAudioQueue.push_back(entry); int64_t audioTimeUs; (buffer->meta())->findInt64("timeUs", &audioTimeUs); if ((mHasVideo && mIsFirstVideoframeReceived) || !mHasVideo){ postDrainAudioQueue(); return; } else { mPendingPostAudioDrains = true; DPR_MSG_HIGH("Not rendering Audio Sample with TS: %lld as Video frame is not decoded", audioTimeUs); } } else { mVideoQueue.push_back(entry); int64_t videoTimeUs; (buffer->meta())->findInt64("timeUs", &videoTimeUs); if (!mIsFirstVideoframeReceived) { mIsFirstVideoframeReceived = true; DPR_MSG_HIGH("Received first video Sample with TS: %lld", videoTimeUs); if (mPendingPostAudioDrains) { mPendingPostAudioDrains = false; postDrainAudioQueue(); } } postDrainVideoQueue(); } if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) { return; } sp<ABuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer; sp<ABuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer; if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) { // EOS signalled on either queue. syncQueuesDone(); return; } int64_t firstAudioTimeUs; int64_t firstVideoTimeUs; CHECK(firstAudioBuffer->meta() ->findInt64("timeUs", &firstAudioTimeUs)); CHECK(firstVideoBuffer->meta() ->findInt64("timeUs", &firstVideoTimeUs)); int64_t diff = firstVideoTimeUs - firstAudioTimeUs; DPR_MSG_LOW("queueDiff = %.2f secs", diff / 1E6); if (diff > 100000ll) { // Audio data starts More than 0.1 secs before video. // Drop some audio. (*mAudioQueue.begin()).mNotifyConsumed->post(); mAudioQueue.erase(mAudioQueue.begin()); return; } syncQueuesDone(); }
void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) { int32_t audio; CHECK(msg->findInt32("audio", &audio)); if (audio) { mHasAudio = true; } else { mHasVideo = true; } if (dropBufferWhileFlushing(audio, msg)) { return; } sp<ABuffer> buffer; CHECK(msg->findBuffer("buffer", &buffer)); sp<AMessage> notifyConsumed; CHECK(msg->findMessage("notifyConsumed", ¬ifyConsumed)); QueueEntry entry; entry.mBuffer = buffer; entry.mNotifyConsumed = notifyConsumed; entry.mOffset = 0; entry.mFinalResult = OK; if (audio) { mDropvideo = true; ALOGD(" audio data input"); mAudioQueue.push_back(entry); postDrainAudioQueue(); } else { mVideoQueue.push_back(entry); postDrainVideoQueue(); } if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) { return; } sp<ABuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer; sp<ABuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer; if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) { // EOS signalled on either queue. syncQueuesDone(); return; } int64_t firstAudioTimeUs; int64_t firstVideoTimeUs; CHECK(firstAudioBuffer->meta() ->findInt64("timeUs", &firstAudioTimeUs)); CHECK(firstVideoBuffer->meta() ->findInt64("timeUs", &firstVideoTimeUs)); int64_t diff = firstVideoTimeUs - firstAudioTimeUs; ALOGV("queueDiff = %.2f secs", diff / 1E6); if (diff > 100000ll) { // Audio data starts More than 0.1 secs before video. // Drop some audio. (*mAudioQueue.begin()).mNotifyConsumed->post(); mAudioQueue.erase(mAudioQueue.begin()); return; } #ifndef ANDROID_DEFAULT_CODE if(diff < -100000ll) { // video data starts More than 0.1 secs before audio. // Drop some video. ALOGE("before playback, video is early than audio drop diff = %.2f", diff / 1E6); (*mVideoQueue.begin()).mNotifyConsumed->post(); mVideoQueue.erase(mVideoQueue.begin()); return; } #endif syncQueuesDone(); }