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