1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <inttypes.h> 18 19 #define LOG_TAG "GraphicBufferSource" 20 //#define LOG_NDEBUG 0 21 #include <utils/Log.h> 22 23 #include "GraphicBufferSource.h" 24 25 #include <OMX_Core.h> 26 #include <OMX_IndexExt.h> 27 #include <media/stagefright/foundation/ADebug.h> 28 #include <media/stagefright/foundation/AMessage.h> 29 30 #include <media/hardware/MetadataBufferType.h> 31 #include <ui/GraphicBuffer.h> 32 #include <gui/BufferItem.h> 33 #include <HardwareAPI.h> 34 35 #include <inttypes.h> 36 #include "FrameDropper.h" 37 38 namespace android { 39 40 static const bool EXTRA_CHECK = true; 41 42 GraphicBufferSource::PersistentProxyListener::PersistentProxyListener( 43 const wp<IGraphicBufferConsumer> &consumer, 44 const wp<ConsumerListener>& consumerListener) : 45 mConsumerListener(consumerListener), 46 mConsumer(consumer) {} 47 48 GraphicBufferSource::PersistentProxyListener::~PersistentProxyListener() {} 49 50 void GraphicBufferSource::PersistentProxyListener::onFrameAvailable( 51 const BufferItem& item) { 52 sp<ConsumerListener> listener(mConsumerListener.promote()); 53 if (listener != NULL) { 54 listener->onFrameAvailable(item); 55 } else { 56 sp<IGraphicBufferConsumer> consumer(mConsumer.promote()); 57 if (consumer == NULL) { 58 return; 59 } 60 BufferItem bi; 61 status_t err = consumer->acquireBuffer(&bi, 0); 62 if (err != OK) { 63 ALOGE("PersistentProxyListener: acquireBuffer failed (%d)", err); 64 return; 65 } 66 67 err = consumer->detachBuffer(bi.mBuf); 68 if (err != OK) { 69 ALOGE("PersistentProxyListener: detachBuffer failed (%d)", err); 70 return; 71 } 72 73 err = consumer->attachBuffer(&bi.mBuf, bi.mGraphicBuffer); 74 if (err != OK) { 75 ALOGE("PersistentProxyListener: attachBuffer failed (%d)", err); 76 return; 77 } 78 79 err = consumer->releaseBuffer(bi.mBuf, 0, 80 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, bi.mFence); 81 if (err != OK) { 82 ALOGE("PersistentProxyListener: releaseBuffer failed (%d)", err); 83 } 84 } 85 } 86 87 void GraphicBufferSource::PersistentProxyListener::onFrameReplaced( 88 const BufferItem& item) { 89 sp<ConsumerListener> listener(mConsumerListener.promote()); 90 if (listener != NULL) { 91 listener->onFrameReplaced(item); 92 } 93 } 94 95 void GraphicBufferSource::PersistentProxyListener::onBuffersReleased() { 96 sp<ConsumerListener> listener(mConsumerListener.promote()); 97 if (listener != NULL) { 98 listener->onBuffersReleased(); 99 } 100 } 101 102 void GraphicBufferSource::PersistentProxyListener::onSidebandStreamChanged() { 103 sp<ConsumerListener> listener(mConsumerListener.promote()); 104 if (listener != NULL) { 105 listener->onSidebandStreamChanged(); 106 } 107 } 108 109 GraphicBufferSource::GraphicBufferSource( 110 OMXNodeInstance* nodeInstance, 111 uint32_t bufferWidth, 112 uint32_t bufferHeight, 113 uint32_t bufferCount, 114 uint32_t consumerUsage, 115 const sp<IGraphicBufferConsumer> &consumer) : 116 mInitCheck(UNKNOWN_ERROR), 117 mNodeInstance(nodeInstance), 118 mExecuting(false), 119 mSuspended(false), 120 mIsPersistent(false), 121 mConsumer(consumer), 122 mNumFramesAvailable(0), 123 mNumBufferAcquired(0), 124 mEndOfStream(false), 125 mEndOfStreamSent(false), 126 mMaxTimestampGapUs(-1ll), 127 mPrevOriginalTimeUs(-1ll), 128 mPrevModifiedTimeUs(-1ll), 129 mSkipFramesBeforeNs(-1ll), 130 mRepeatAfterUs(-1ll), 131 mRepeatLastFrameGeneration(0), 132 mRepeatLastFrameTimestamp(-1ll), 133 mLatestBufferId(-1), 134 mLatestBufferFrameNum(0), 135 mLatestBufferUseCount(0), 136 mLatestBufferFence(Fence::NO_FENCE), 137 mRepeatBufferDeferred(false), 138 mTimePerCaptureUs(-1ll), 139 mTimePerFrameUs(-1ll), 140 mPrevCaptureUs(-1ll), 141 mPrevFrameUs(-1ll) { 142 143 ALOGV("GraphicBufferSource w=%u h=%u c=%u", 144 bufferWidth, bufferHeight, bufferCount); 145 146 if (bufferWidth == 0 || bufferHeight == 0) { 147 ALOGE("Invalid dimensions %ux%u", bufferWidth, bufferHeight); 148 mInitCheck = BAD_VALUE; 149 return; 150 } 151 152 if (mConsumer == NULL) { 153 String8 name("GraphicBufferSource"); 154 155 BufferQueue::createBufferQueue(&mProducer, &mConsumer); 156 mConsumer->setConsumerName(name); 157 158 // use consumer usage bits queried from encoder, but always add HW_VIDEO_ENCODER 159 // for backward compatibility. 160 consumerUsage |= GRALLOC_USAGE_HW_VIDEO_ENCODER; 161 mConsumer->setConsumerUsageBits(consumerUsage); 162 163 mInitCheck = mConsumer->setMaxAcquiredBufferCount(bufferCount); 164 if (mInitCheck != NO_ERROR) { 165 ALOGE("Unable to set BQ max acquired buffer count to %u: %d", 166 bufferCount, mInitCheck); 167 return; 168 } 169 } else { 170 mIsPersistent = true; 171 } 172 mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight); 173 // Note that we can't create an sp<...>(this) in a ctor that will not keep a 174 // reference once the ctor ends, as that would cause the refcount of 'this' 175 // dropping to 0 at the end of the ctor. Since all we need is a wp<...> 176 // that's what we create. 177 wp<BufferQueue::ConsumerListener> listener = static_cast<BufferQueue::ConsumerListener*>(this); 178 sp<IConsumerListener> proxy; 179 if (!mIsPersistent) { 180 proxy = new BufferQueue::ProxyConsumerListener(listener); 181 } else { 182 proxy = new PersistentProxyListener(mConsumer, listener); 183 } 184 185 mInitCheck = mConsumer->consumerConnect(proxy, false); 186 if (mInitCheck != NO_ERROR) { 187 ALOGE("Error connecting to BufferQueue: %s (%d)", 188 strerror(-mInitCheck), mInitCheck); 189 return; 190 } 191 192 CHECK(mInitCheck == NO_ERROR); 193 } 194 195 GraphicBufferSource::~GraphicBufferSource() { 196 if (mLatestBufferId >= 0) { 197 releaseBuffer( 198 mLatestBufferId, mLatestBufferFrameNum, 199 mBufferSlot[mLatestBufferId], mLatestBufferFence); 200 } 201 if (mNumBufferAcquired != 0) { 202 ALOGW("potential buffer leak (acquired %d)", mNumBufferAcquired); 203 } 204 if (mConsumer != NULL && !mIsPersistent) { 205 status_t err = mConsumer->consumerDisconnect(); 206 if (err != NO_ERROR) { 207 ALOGW("consumerDisconnect failed: %d", err); 208 } 209 } 210 } 211 212 void GraphicBufferSource::omxExecuting() { 213 Mutex::Autolock autoLock(mMutex); 214 ALOGV("--> executing; avail=%zu, codec vec size=%zd", 215 mNumFramesAvailable, mCodecBuffers.size()); 216 CHECK(!mExecuting); 217 mExecuting = true; 218 219 // Start by loading up as many buffers as possible. We want to do this, 220 // rather than just submit the first buffer, to avoid a degenerate case: 221 // if all BQ buffers arrive before we start executing, and we only submit 222 // one here, the other BQ buffers will just sit until we get notified 223 // that the codec buffer has been released. We'd then acquire and 224 // submit a single additional buffer, repeatedly, never using more than 225 // one codec buffer simultaneously. (We could instead try to submit 226 // all BQ buffers whenever any codec buffer is freed, but if we get the 227 // initial conditions right that will never be useful.) 228 while (mNumFramesAvailable) { 229 if (!fillCodecBuffer_l()) { 230 ALOGV("stop load with frames available (codecAvail=%d)", 231 isCodecBufferAvailable_l()); 232 break; 233 } 234 } 235 236 ALOGV("done loading initial frames, avail=%zu", mNumFramesAvailable); 237 238 // If EOS has already been signaled, and there are no more frames to 239 // submit, try to send EOS now as well. 240 if (mEndOfStream && mNumFramesAvailable == 0) { 241 submitEndOfInputStream_l(); 242 } 243 244 if (mRepeatAfterUs > 0ll && mLooper == NULL) { 245 mReflector = new AHandlerReflector<GraphicBufferSource>(this); 246 247 mLooper = new ALooper; 248 mLooper->registerHandler(mReflector); 249 mLooper->start(); 250 251 if (mLatestBufferId >= 0) { 252 sp<AMessage> msg = 253 new AMessage(kWhatRepeatLastFrame, mReflector); 254 255 msg->setInt32("generation", ++mRepeatLastFrameGeneration); 256 msg->post(mRepeatAfterUs); 257 } 258 } 259 } 260 261 void GraphicBufferSource::omxIdle() { 262 ALOGV("omxIdle"); 263 264 Mutex::Autolock autoLock(mMutex); 265 266 if (mExecuting) { 267 // We are only interested in the transition from executing->idle, 268 // not loaded->idle. 269 mExecuting = false; 270 } 271 } 272 273 void GraphicBufferSource::omxLoaded(){ 274 Mutex::Autolock autoLock(mMutex); 275 if (!mExecuting) { 276 // This can happen if something failed very early. 277 ALOGW("Dropped back down to Loaded without Executing"); 278 } 279 280 if (mLooper != NULL) { 281 mLooper->unregisterHandler(mReflector->id()); 282 mReflector.clear(); 283 284 mLooper->stop(); 285 mLooper.clear(); 286 } 287 288 ALOGV("--> loaded; avail=%zu eos=%d eosSent=%d", 289 mNumFramesAvailable, mEndOfStream, mEndOfStreamSent); 290 291 // Codec is no longer executing. Discard all codec-related state. 292 mCodecBuffers.clear(); 293 // TODO: scan mCodecBuffers to verify that all mGraphicBuffer entries 294 // are null; complain if not 295 296 mExecuting = false; 297 } 298 299 void GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) { 300 Mutex::Autolock autoLock(mMutex); 301 302 if (mExecuting) { 303 // This should never happen -- buffers can only be allocated when 304 // transitioning from "loaded" to "idle". 305 ALOGE("addCodecBuffer: buffer added while executing"); 306 return; 307 } 308 309 ALOGV("addCodecBuffer h=%p size=%" PRIu32 " p=%p", 310 header, header->nAllocLen, header->pBuffer); 311 CodecBuffer codecBuffer; 312 codecBuffer.mHeader = header; 313 mCodecBuffers.add(codecBuffer); 314 } 315 316 void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header, int fenceFd) { 317 Mutex::Autolock autoLock(mMutex); 318 if (!mExecuting) { 319 return; 320 } 321 322 int cbi = findMatchingCodecBuffer_l(header); 323 if (cbi < 0) { 324 // This should never happen. 325 ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header); 326 if (fenceFd >= 0) { 327 ::close(fenceFd); 328 } 329 return; 330 } 331 332 ALOGV("codecBufferEmptied h=%p size=%" PRIu32 " filled=%" PRIu32 " p=%p", 333 header, header->nAllocLen, header->nFilledLen, 334 header->pBuffer); 335 CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 336 337 // header->nFilledLen may not be the original value, so we can't compare 338 // that to zero to see of this was the EOS buffer. Instead we just 339 // see if the GraphicBuffer reference was null, which should only ever 340 // happen for EOS. 341 if (codecBuffer.mGraphicBuffer == NULL) { 342 if (!(mEndOfStream && mEndOfStreamSent)) { 343 // This can happen when broken code sends us the same buffer 344 // twice in a row. 345 ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer " 346 "(buffer emptied twice?)"); 347 } 348 // No GraphicBuffer to deal with, no additional input or output is 349 // expected, so just return. 350 if (fenceFd >= 0) { 351 ::close(fenceFd); 352 } 353 return; 354 } 355 356 if (EXTRA_CHECK && header->nAllocLen >= sizeof(MetadataBufferType)) { 357 // Pull the graphic buffer handle back out of the buffer, and confirm 358 // that it matches expectations. 359 OMX_U8* data = header->pBuffer; 360 MetadataBufferType type = *(MetadataBufferType *)data; 361 if (type == kMetadataBufferTypeGrallocSource 362 && header->nAllocLen >= sizeof(VideoGrallocMetadata)) { 363 VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)data; 364 if (grallocMeta.pHandle != codecBuffer.mGraphicBuffer->handle) { 365 // should never happen 366 ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p", 367 grallocMeta.pHandle, codecBuffer.mGraphicBuffer->handle); 368 CHECK(!"codecBufferEmptied: mismatched buffer"); 369 } 370 } else if (type == kMetadataBufferTypeANWBuffer 371 && header->nAllocLen >= sizeof(VideoNativeMetadata)) { 372 VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)data; 373 if (nativeMeta.pBuffer != codecBuffer.mGraphicBuffer->getNativeBuffer()) { 374 // should never happen 375 ALOGE("codecBufferEmptied: buffer is %p, expected %p", 376 nativeMeta.pBuffer, codecBuffer.mGraphicBuffer->getNativeBuffer()); 377 CHECK(!"codecBufferEmptied: mismatched buffer"); 378 } 379 } 380 } 381 382 // Find matching entry in our cached copy of the BufferQueue slots. 383 // If we find a match, release that slot. If we don't, the BufferQueue 384 // has dropped that GraphicBuffer, and there's nothing for us to release. 385 int id = codecBuffer.mBuf; 386 sp<Fence> fence = new Fence(fenceFd); 387 if (mBufferSlot[id] != NULL && 388 mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) { 389 ALOGV("cbi %d matches bq slot %d, handle=%p", 390 cbi, id, mBufferSlot[id]->handle); 391 392 if (id == mLatestBufferId) { 393 CHECK_GT(mLatestBufferUseCount--, 0); 394 } else { 395 releaseBuffer(id, codecBuffer.mFrameNumber, mBufferSlot[id], fence); 396 } 397 } else { 398 ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d", 399 cbi); 400 // we will not reuse codec buffer, so there is no need to wait for fence 401 } 402 403 // Mark the codec buffer as available by clearing the GraphicBuffer ref. 404 codecBuffer.mGraphicBuffer = NULL; 405 406 if (mNumFramesAvailable) { 407 // Fill this codec buffer. 408 CHECK(!mEndOfStreamSent); 409 ALOGV("buffer freed, %zu frames avail (eos=%d)", 410 mNumFramesAvailable, mEndOfStream); 411 fillCodecBuffer_l(); 412 } else if (mEndOfStream) { 413 // No frames available, but EOS is pending, so use this buffer to 414 // send that. 415 ALOGV("buffer freed, EOS pending"); 416 submitEndOfInputStream_l(); 417 } else if (mRepeatBufferDeferred) { 418 bool success = repeatLatestBuffer_l(); 419 if (success) { 420 ALOGV("deferred repeatLatestBuffer_l SUCCESS"); 421 } else { 422 ALOGV("deferred repeatLatestBuffer_l FAILURE"); 423 } 424 mRepeatBufferDeferred = false; 425 } 426 427 return; 428 } 429 430 void GraphicBufferSource::codecBufferFilled(OMX_BUFFERHEADERTYPE* header) { 431 Mutex::Autolock autoLock(mMutex); 432 433 if (mMaxTimestampGapUs > 0ll 434 && !(header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { 435 ssize_t index = mOriginalTimeUs.indexOfKey(header->nTimeStamp); 436 if (index >= 0) { 437 ALOGV("OUT timestamp: %lld -> %lld", 438 static_cast<long long>(header->nTimeStamp), 439 static_cast<long long>(mOriginalTimeUs[index])); 440 header->nTimeStamp = mOriginalTimeUs[index]; 441 mOriginalTimeUs.removeItemsAt(index); 442 } else { 443 // giving up the effort as encoder doesn't appear to preserve pts 444 ALOGW("giving up limiting timestamp gap (pts = %lld)", 445 header->nTimeStamp); 446 mMaxTimestampGapUs = -1ll; 447 } 448 if (mOriginalTimeUs.size() > BufferQueue::NUM_BUFFER_SLOTS) { 449 // something terribly wrong must have happened, giving up... 450 ALOGE("mOriginalTimeUs has too many entries (%zu)", 451 mOriginalTimeUs.size()); 452 mMaxTimestampGapUs = -1ll; 453 } 454 } 455 } 456 457 void GraphicBufferSource::suspend(bool suspend) { 458 Mutex::Autolock autoLock(mMutex); 459 460 if (suspend) { 461 mSuspended = true; 462 463 while (mNumFramesAvailable > 0) { 464 BufferItem item; 465 status_t err = mConsumer->acquireBuffer(&item, 0); 466 467 if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 468 // shouldn't happen. 469 ALOGW("suspend: frame was not available"); 470 break; 471 } else if (err != OK) { 472 ALOGW("suspend: acquireBuffer returned err=%d", err); 473 break; 474 } 475 476 ++mNumBufferAcquired; 477 --mNumFramesAvailable; 478 479 releaseBuffer(item.mBuf, item.mFrameNumber, 480 item.mGraphicBuffer, item.mFence); 481 } 482 return; 483 } 484 485 mSuspended = false; 486 487 if (mExecuting && mNumFramesAvailable == 0 && mRepeatBufferDeferred) { 488 if (repeatLatestBuffer_l()) { 489 ALOGV("suspend/deferred repeatLatestBuffer_l SUCCESS"); 490 491 mRepeatBufferDeferred = false; 492 } else { 493 ALOGV("suspend/deferred repeatLatestBuffer_l FAILURE"); 494 } 495 } 496 } 497 498 bool GraphicBufferSource::fillCodecBuffer_l() { 499 CHECK(mExecuting && mNumFramesAvailable > 0); 500 501 if (mSuspended) { 502 return false; 503 } 504 505 int cbi = findAvailableCodecBuffer_l(); 506 if (cbi < 0) { 507 // No buffers available, bail. 508 ALOGV("fillCodecBuffer_l: no codec buffers, avail now %zu", 509 mNumFramesAvailable); 510 return false; 511 } 512 513 ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%zu", 514 mNumFramesAvailable); 515 BufferItem item; 516 status_t err = mConsumer->acquireBuffer(&item, 0); 517 if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 518 // shouldn't happen 519 ALOGW("fillCodecBuffer_l: frame was not available"); 520 return false; 521 } else if (err != OK) { 522 // now what? fake end-of-stream? 523 ALOGW("fillCodecBuffer_l: acquireBuffer returned err=%d", err); 524 return false; 525 } 526 527 mNumBufferAcquired++; 528 mNumFramesAvailable--; 529 530 // If this is the first time we're seeing this buffer, add it to our 531 // slot table. 532 if (item.mGraphicBuffer != NULL) { 533 ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf); 534 mBufferSlot[item.mBuf] = item.mGraphicBuffer; 535 } 536 537 err = UNKNOWN_ERROR; 538 539 // only submit sample if start time is unspecified, or sample 540 // is queued after the specified start time 541 bool dropped = false; 542 if (mSkipFramesBeforeNs < 0ll || item.mTimestamp >= mSkipFramesBeforeNs) { 543 // if start time is set, offset time stamp by start time 544 if (mSkipFramesBeforeNs > 0) { 545 item.mTimestamp -= mSkipFramesBeforeNs; 546 } 547 548 int64_t timeUs = item.mTimestamp / 1000; 549 if (mFrameDropper != NULL && mFrameDropper->shouldDrop(timeUs)) { 550 ALOGV("skipping frame (%lld) to meet max framerate", static_cast<long long>(timeUs)); 551 // set err to OK so that the skipped frame can still be saved as the lastest frame 552 err = OK; 553 dropped = true; 554 } else { 555 err = submitBuffer_l(item, cbi); 556 } 557 } 558 559 if (err != OK) { 560 ALOGV("submitBuffer_l failed, releasing bq buf %d", item.mBuf); 561 releaseBuffer(item.mBuf, item.mFrameNumber, item.mGraphicBuffer, item.mFence); 562 } else { 563 ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi); 564 setLatestBuffer_l(item, dropped); 565 } 566 567 return true; 568 } 569 570 bool GraphicBufferSource::repeatLatestBuffer_l() { 571 CHECK(mExecuting && mNumFramesAvailable == 0); 572 573 if (mLatestBufferId < 0 || mSuspended) { 574 return false; 575 } 576 if (mBufferSlot[mLatestBufferId] == NULL) { 577 // This can happen if the remote side disconnects, causing 578 // onBuffersReleased() to NULL out our copy of the slots. The 579 // buffer is gone, so we have nothing to show. 580 // 581 // To be on the safe side we try to release the buffer. 582 ALOGD("repeatLatestBuffer_l: slot was NULL"); 583 mConsumer->releaseBuffer( 584 mLatestBufferId, 585 mLatestBufferFrameNum, 586 EGL_NO_DISPLAY, 587 EGL_NO_SYNC_KHR, 588 mLatestBufferFence); 589 mLatestBufferId = -1; 590 mLatestBufferFrameNum = 0; 591 mLatestBufferFence = Fence::NO_FENCE; 592 return false; 593 } 594 595 int cbi = findAvailableCodecBuffer_l(); 596 if (cbi < 0) { 597 // No buffers available, bail. 598 ALOGV("repeatLatestBuffer_l: no codec buffers."); 599 return false; 600 } 601 602 BufferItem item; 603 item.mBuf = mLatestBufferId; 604 item.mFrameNumber = mLatestBufferFrameNum; 605 item.mTimestamp = mRepeatLastFrameTimestamp; 606 item.mFence = mLatestBufferFence; 607 608 status_t err = submitBuffer_l(item, cbi); 609 610 if (err != OK) { 611 return false; 612 } 613 614 ++mLatestBufferUseCount; 615 616 /* repeat last frame up to kRepeatLastFrameCount times. 617 * in case of static scene, a single repeat might not get rid of encoder 618 * ghosting completely, refresh a couple more times to get better quality 619 */ 620 if (--mRepeatLastFrameCount > 0) { 621 mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 622 623 if (mReflector != NULL) { 624 sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector); 625 msg->setInt32("generation", ++mRepeatLastFrameGeneration); 626 msg->post(mRepeatAfterUs); 627 } 628 } 629 630 return true; 631 } 632 633 void GraphicBufferSource::setLatestBuffer_l( 634 const BufferItem &item, bool dropped) { 635 ALOGV("setLatestBuffer_l"); 636 637 if (mLatestBufferId >= 0) { 638 if (mLatestBufferUseCount == 0) { 639 releaseBuffer(mLatestBufferId, mLatestBufferFrameNum, 640 mBufferSlot[mLatestBufferId], mLatestBufferFence); 641 // mLatestBufferFence will be set to new fence just below 642 } 643 } 644 645 mLatestBufferId = item.mBuf; 646 mLatestBufferFrameNum = item.mFrameNumber; 647 mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000; 648 649 mLatestBufferUseCount = dropped ? 0 : 1; 650 mRepeatBufferDeferred = false; 651 mRepeatLastFrameCount = kRepeatLastFrameCount; 652 mLatestBufferFence = item.mFence; 653 654 if (mReflector != NULL) { 655 sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector); 656 msg->setInt32("generation", ++mRepeatLastFrameGeneration); 657 msg->post(mRepeatAfterUs); 658 } 659 } 660 661 status_t GraphicBufferSource::signalEndOfInputStream() { 662 Mutex::Autolock autoLock(mMutex); 663 ALOGV("signalEndOfInputStream: exec=%d avail=%zu eos=%d", 664 mExecuting, mNumFramesAvailable, mEndOfStream); 665 666 if (mEndOfStream) { 667 ALOGE("EOS was already signaled"); 668 return INVALID_OPERATION; 669 } 670 671 // Set the end-of-stream flag. If no frames are pending from the 672 // BufferQueue, and a codec buffer is available, and we're executing, 673 // we initiate the EOS from here. Otherwise, we'll let 674 // codecBufferEmptied() (or omxExecuting) do it. 675 // 676 // Note: if there are no pending frames and all codec buffers are 677 // available, we *must* submit the EOS from here or we'll just 678 // stall since no future events are expected. 679 mEndOfStream = true; 680 681 if (mExecuting && mNumFramesAvailable == 0) { 682 submitEndOfInputStream_l(); 683 } 684 685 return OK; 686 } 687 688 int64_t GraphicBufferSource::getTimestamp(const BufferItem &item) { 689 int64_t timeUs = item.mTimestamp / 1000; 690 691 if (mTimePerCaptureUs > 0ll) { 692 // Time lapse or slow motion mode 693 if (mPrevCaptureUs < 0ll) { 694 // first capture 695 mPrevCaptureUs = timeUs; 696 mPrevFrameUs = timeUs; 697 } else { 698 // snap to nearest capture point 699 int64_t nFrames = (timeUs + mTimePerCaptureUs / 2 - mPrevCaptureUs) 700 / mTimePerCaptureUs; 701 if (nFrames <= 0) { 702 // skip this frame as it's too close to previous capture 703 ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs)); 704 return -1; 705 } 706 mPrevCaptureUs = mPrevCaptureUs + nFrames * mTimePerCaptureUs; 707 mPrevFrameUs += mTimePerFrameUs * nFrames; 708 } 709 710 ALOGV("timeUs %lld, captureUs %lld, frameUs %lld", 711 static_cast<long long>(timeUs), 712 static_cast<long long>(mPrevCaptureUs), 713 static_cast<long long>(mPrevFrameUs)); 714 715 return mPrevFrameUs; 716 } else if (mMaxTimestampGapUs > 0ll) { 717 /* Cap timestamp gap between adjacent frames to specified max 718 * 719 * In the scenario of cast mirroring, encoding could be suspended for 720 * prolonged periods. Limiting the pts gap to workaround the problem 721 * where encoder's rate control logic produces huge frames after a 722 * long period of suspension. 723 */ 724 725 int64_t originalTimeUs = timeUs; 726 if (mPrevOriginalTimeUs >= 0ll) { 727 if (originalTimeUs < mPrevOriginalTimeUs) { 728 // Drop the frame if it's going backward in time. Bad timestamp 729 // could disrupt encoder's rate control completely. 730 ALOGW("Dropping frame that's going backward in time"); 731 return -1; 732 } 733 int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs; 734 timeUs = (timestampGapUs < mMaxTimestampGapUs ? 735 timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs; 736 } 737 mPrevOriginalTimeUs = originalTimeUs; 738 mPrevModifiedTimeUs = timeUs; 739 mOriginalTimeUs.add(timeUs, originalTimeUs); 740 ALOGV("IN timestamp: %lld -> %lld", 741 static_cast<long long>(originalTimeUs), 742 static_cast<long long>(timeUs)); 743 } 744 745 return timeUs; 746 } 747 748 status_t GraphicBufferSource::submitBuffer_l(const BufferItem &item, int cbi) { 749 ALOGV("submitBuffer_l cbi=%d", cbi); 750 751 int64_t timeUs = getTimestamp(item); 752 if (timeUs < 0ll) { 753 return UNKNOWN_ERROR; 754 } 755 756 CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 757 codecBuffer.mGraphicBuffer = mBufferSlot[item.mBuf]; 758 codecBuffer.mBuf = item.mBuf; 759 codecBuffer.mFrameNumber = item.mFrameNumber; 760 761 OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 762 sp<GraphicBuffer> buffer = codecBuffer.mGraphicBuffer; 763 status_t err = mNodeInstance->emptyGraphicBuffer( 764 header, buffer, OMX_BUFFERFLAG_ENDOFFRAME, timeUs, 765 item.mFence->isValid() ? item.mFence->dup() : -1); 766 if (err != OK) { 767 ALOGW("WARNING: emptyNativeWindowBuffer failed: 0x%x", err); 768 codecBuffer.mGraphicBuffer = NULL; 769 return err; 770 } 771 772 ALOGV("emptyNativeWindowBuffer succeeded, h=%p p=%p buf=%p bufhandle=%p", 773 header, header->pBuffer, buffer->getNativeBuffer(), buffer->handle); 774 return OK; 775 } 776 777 void GraphicBufferSource::submitEndOfInputStream_l() { 778 CHECK(mEndOfStream); 779 if (mEndOfStreamSent) { 780 ALOGV("EOS already sent"); 781 return; 782 } 783 784 int cbi = findAvailableCodecBuffer_l(); 785 if (cbi < 0) { 786 ALOGV("submitEndOfInputStream_l: no codec buffers available"); 787 return; 788 } 789 790 // We reject any additional incoming graphic buffers, so there's no need 791 // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as 792 // in-use. 793 CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); 794 795 OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; 796 status_t err = mNodeInstance->emptyGraphicBuffer( 797 header, NULL /* buffer */, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS, 798 0 /* timestamp */, -1 /* fenceFd */); 799 if (err != OK) { 800 ALOGW("emptyDirectBuffer EOS failed: 0x%x", err); 801 } else { 802 ALOGV("submitEndOfInputStream_l: buffer submitted, header=%p cbi=%d", 803 header, cbi); 804 mEndOfStreamSent = true; 805 } 806 } 807 808 int GraphicBufferSource::findAvailableCodecBuffer_l() { 809 CHECK(mCodecBuffers.size() > 0); 810 811 for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 812 if (mCodecBuffers[i].mGraphicBuffer == NULL) { 813 return i; 814 } 815 } 816 return -1; 817 } 818 819 int GraphicBufferSource::findMatchingCodecBuffer_l( 820 const OMX_BUFFERHEADERTYPE* header) { 821 for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) { 822 if (mCodecBuffers[i].mHeader == header) { 823 return i; 824 } 825 } 826 return -1; 827 } 828 829 /* 830 * Releases an acquired buffer back to the consumer for either persistent 831 * or non-persistent surfaces. 832 * 833 * id: buffer slot to release (in persistent case the id might be changed) 834 * frameNum: frame number of the frame being released 835 * buffer: GraphicBuffer pointer to release (note this must not be & as we 836 * will clear the original mBufferSlot in persistent case) 837 * fence: fence of the frame being released 838 */ 839 void GraphicBufferSource::releaseBuffer( 840 int &id, uint64_t frameNum, 841 const sp<GraphicBuffer> buffer, const sp<Fence> &fence) { 842 if (mIsPersistent) { 843 mConsumer->detachBuffer(id); 844 mBufferSlot[id] = NULL; 845 846 if (mConsumer->attachBuffer(&id, buffer) == OK) { 847 mConsumer->releaseBuffer( 848 id, 0, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 849 } 850 } else { 851 mConsumer->releaseBuffer( 852 id, frameNum, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence); 853 } 854 id = -1; // invalidate id 855 mNumBufferAcquired--; 856 } 857 858 // BufferQueue::ConsumerListener callback 859 void GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) { 860 Mutex::Autolock autoLock(mMutex); 861 862 ALOGV("onFrameAvailable exec=%d avail=%zu", 863 mExecuting, mNumFramesAvailable); 864 865 if (mEndOfStream || mSuspended) { 866 if (mEndOfStream) { 867 // This should only be possible if a new buffer was queued after 868 // EOS was signaled, i.e. the app is misbehaving. 869 870 ALOGW("onFrameAvailable: EOS is set, ignoring frame"); 871 } else { 872 ALOGV("onFrameAvailable: suspended, ignoring frame"); 873 } 874 875 BufferItem item; 876 status_t err = mConsumer->acquireBuffer(&item, 0); 877 if (err == OK) { 878 mNumBufferAcquired++; 879 880 // If this is the first time we're seeing this buffer, add it to our 881 // slot table. 882 if (item.mGraphicBuffer != NULL) { 883 ALOGV("onFrameAvailable: setting mBufferSlot %d", item.mBuf); 884 mBufferSlot[item.mBuf] = item.mGraphicBuffer; 885 } 886 887 releaseBuffer(item.mBuf, item.mFrameNumber, 888 item.mGraphicBuffer, item.mFence); 889 } 890 return; 891 } 892 893 mNumFramesAvailable++; 894 895 mRepeatBufferDeferred = false; 896 ++mRepeatLastFrameGeneration; 897 898 if (mExecuting) { 899 fillCodecBuffer_l(); 900 } 901 } 902 903 // BufferQueue::ConsumerListener callback 904 void GraphicBufferSource::onBuffersReleased() { 905 Mutex::Autolock lock(mMutex); 906 907 uint64_t slotMask; 908 if (mConsumer->getReleasedBuffers(&slotMask) != NO_ERROR) { 909 ALOGW("onBuffersReleased: unable to get released buffer set"); 910 slotMask = 0xffffffffffffffffULL; 911 } 912 913 ALOGV("onBuffersReleased: 0x%016" PRIx64, slotMask); 914 915 for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 916 if ((slotMask & 0x01) != 0) { 917 mBufferSlot[i] = NULL; 918 } 919 slotMask >>= 1; 920 } 921 } 922 923 // BufferQueue::ConsumerListener callback 924 void GraphicBufferSource::onSidebandStreamChanged() { 925 ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams"); 926 } 927 928 status_t GraphicBufferSource::setRepeatPreviousFrameDelayUs( 929 int64_t repeatAfterUs) { 930 Mutex::Autolock autoLock(mMutex); 931 932 if (mExecuting || repeatAfterUs <= 0ll) { 933 return INVALID_OPERATION; 934 } 935 936 mRepeatAfterUs = repeatAfterUs; 937 938 return OK; 939 } 940 941 status_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) { 942 Mutex::Autolock autoLock(mMutex); 943 944 if (mExecuting || maxGapUs <= 0ll) { 945 return INVALID_OPERATION; 946 } 947 948 mMaxTimestampGapUs = maxGapUs; 949 950 return OK; 951 } 952 953 status_t GraphicBufferSource::setMaxFps(float maxFps) { 954 Mutex::Autolock autoLock(mMutex); 955 956 if (mExecuting) { 957 return INVALID_OPERATION; 958 } 959 960 mFrameDropper = new FrameDropper(); 961 status_t err = mFrameDropper->setMaxFrameRate(maxFps); 962 if (err != OK) { 963 mFrameDropper.clear(); 964 return err; 965 } 966 967 return OK; 968 } 969 970 void GraphicBufferSource::setSkipFramesBeforeUs(int64_t skipFramesBeforeUs) { 971 Mutex::Autolock autoLock(mMutex); 972 973 mSkipFramesBeforeNs = 974 (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll; 975 } 976 977 status_t GraphicBufferSource::setTimeLapseUs(int64_t* data) { 978 Mutex::Autolock autoLock(mMutex); 979 980 if (mExecuting || data[0] <= 0ll || data[1] <= 0ll) { 981 return INVALID_OPERATION; 982 } 983 984 mTimePerFrameUs = data[0]; 985 mTimePerCaptureUs = data[1]; 986 987 return OK; 988 } 989 990 void GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) { 991 switch (msg->what()) { 992 case kWhatRepeatLastFrame: 993 { 994 Mutex::Autolock autoLock(mMutex); 995 996 int32_t generation; 997 CHECK(msg->findInt32("generation", &generation)); 998 999 if (generation != mRepeatLastFrameGeneration) { 1000 // stale 1001 break; 1002 } 1003 1004 if (!mExecuting || mNumFramesAvailable > 0) { 1005 break; 1006 } 1007 1008 bool success = repeatLatestBuffer_l(); 1009 1010 if (success) { 1011 ALOGV("repeatLatestBuffer_l SUCCESS"); 1012 } else { 1013 ALOGV("repeatLatestBuffer_l FAILURE"); 1014 mRepeatBufferDeferred = true; 1015 } 1016 break; 1017 } 1018 1019 default: 1020 TRESPASS(); 1021 } 1022 } 1023 1024 } // namespace android 1025