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