summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/omx
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2015-06-01 10:54:31 -0700
committerLajos Molnar <lajos@google.com>2015-06-02 19:04:16 -0700
commit15ab4996019387f27a48b81cb4774c21502bc0e5 (patch)
treecff50b03c2785db5944f0bc310f9c8afaae17b2e /media/libstagefright/omx
parent40b26470dd29e44f1601ceb6e60948586a4d9f88 (diff)
downloadframeworks_av-15ab4996019387f27a48b81cb4774c21502bc0e5.zip
frameworks_av-15ab4996019387f27a48b81cb4774c21502bc0e5.tar.gz
frameworks_av-15ab4996019387f27a48b81cb4774c21502bc0e5.tar.bz2
stagefright: add support for fences in OMX
Pass Fence between Surface and ACodec, and between ACodec and IOMX. Bug: 12386081 Change-Id: Ifdc566979dec0d91ed8b07c3b69d2cf092accc73
Diffstat (limited to 'media/libstagefright/omx')
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.cpp50
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.h3
-rw-r--r--media/libstagefright/omx/OMX.cpp15
-rw-r--r--media/libstagefright/omx/OMXNodeInstance.cpp105
-rw-r--r--media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp10
5 files changed, 134 insertions, 49 deletions
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index f797e63..be91510 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -64,6 +64,7 @@ GraphicBufferSource::GraphicBufferSource(
mLatestBufferId(-1),
mLatestBufferFrameNum(0),
mLatestBufferUseCount(0),
+ mLatestBufferFence(Fence::NO_FENCE),
mRepeatBufferDeferred(false),
mTimePerCaptureUs(-1ll),
mTimePerFrameUs(-1ll),
@@ -226,9 +227,8 @@ void GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) {
mCodecBuffers.add(codecBuffer);
}
-void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
+void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header, int fenceFd) {
Mutex::Autolock autoLock(mMutex);
-
if (!mExecuting) {
return;
}
@@ -237,6 +237,9 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
if (cbi < 0) {
// This should never happen.
ALOGE("codecBufferEmptied: buffer not recognized (h=%p)", header);
+ if (fenceFd >= 0) {
+ ::close(fenceFd);
+ }
return;
}
@@ -258,6 +261,9 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
}
// No GraphicBuffer to deal with, no additional input or output is
// expected, so just return.
+ if (fenceFd >= 0) {
+ ::close(fenceFd);
+ }
return;
}
@@ -291,6 +297,7 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
// If we find a match, release that slot. If we don't, the BufferQueue
// has dropped that GraphicBuffer, and there's nothing for us to release.
int id = codecBuffer.mBuf;
+ sp<Fence> fence = new Fence(fenceFd);
if (mBufferSlot[id] != NULL &&
mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) {
ALOGV("cbi %d matches bq slot %d, handle=%p",
@@ -304,15 +311,16 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
int outSlot;
mConsumer->attachBuffer(&outSlot, mBufferSlot[id]);
mConsumer->releaseBuffer(outSlot, 0,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
+ EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence);
} else {
mConsumer->releaseBuffer(id, codecBuffer.mFrameNumber,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
+ EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence);
}
}
} else {
ALOGV("codecBufferEmptied: no match for emptied buffer in cbi %d",
cbi);
+ // we will not reuse codec buffer, so there is no need to wait for fence
}
// Mark the codec buffer as available by clearing the GraphicBuffer ref.
@@ -394,7 +402,7 @@ void GraphicBufferSource::suspend(bool suspend) {
mConsumer->detachBuffer(item.mBuf);
mConsumer->attachBuffer(&item.mBuf, item.mGraphicBuffer);
mConsumer->releaseBuffer(item.mBuf, 0,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
+ EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
} else {
mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
@@ -447,13 +455,6 @@ bool GraphicBufferSource::fillCodecBuffer_l() {
mNumFramesAvailable--;
- // Wait for it to become available.
- err = item.mFence->waitForever("GraphicBufferSource::fillCodecBuffer_l");
- if (err != OK) {
- ALOGW("failed to wait for buffer fence: %d", err);
- // keep going
- }
-
// If this is the first time we're seeing this buffer, add it to our
// slot table.
if (item.mGraphicBuffer != NULL) {
@@ -489,11 +490,12 @@ bool GraphicBufferSource::fillCodecBuffer_l() {
mConsumer->detachBuffer(item.mBuf);
mConsumer->attachBuffer(&item.mBuf, item.mGraphicBuffer);
mConsumer->releaseBuffer(item.mBuf, 0,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
+ EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
} else {
mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
+ EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
}
+ // item.mFence is released at the end of this method
} else {
ALOGV("buffer submitted (bq %d, cbi %d)", item.mBuf, cbi);
setLatestBuffer_l(item, dropped);
@@ -520,9 +522,10 @@ bool GraphicBufferSource::repeatLatestBuffer_l() {
mLatestBufferFrameNum,
EGL_NO_DISPLAY,
EGL_NO_SYNC_KHR,
- Fence::NO_FENCE);
+ mLatestBufferFence);
mLatestBufferId = -1;
mLatestBufferFrameNum = 0;
+ mLatestBufferFence = Fence::NO_FENCE;
return false;
}
@@ -537,6 +540,7 @@ bool GraphicBufferSource::repeatLatestBuffer_l() {
item.mBuf = mLatestBufferId;
item.mFrameNumber = mLatestBufferFrameNum;
item.mTimestamp = mRepeatLastFrameTimestamp;
+ item.mFence = mLatestBufferFence;
status_t err = submitBuffer_l(item, cbi);
@@ -576,12 +580,13 @@ void GraphicBufferSource::setLatestBuffer_l(
mConsumer->attachBuffer(&outSlot, mBufferSlot[mLatestBufferId]);
mConsumer->releaseBuffer(outSlot, 0,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
+ EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, mLatestBufferFence);
} else {
mConsumer->releaseBuffer(
mLatestBufferId, mLatestBufferFrameNum,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
+ EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, mLatestBufferFence);
}
+ // mLatestBufferFence will be set to new fence just below
}
}
@@ -592,6 +597,7 @@ void GraphicBufferSource::setLatestBuffer_l(
mLatestBufferUseCount = dropped ? 0 : 1;
mRepeatBufferDeferred = false;
mRepeatLastFrameCount = kRepeatLastFrameCount;
+ mLatestBufferFence = item.mFence;
if (mReflector != NULL) {
sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector);
@@ -687,8 +693,7 @@ int64_t GraphicBufferSource::getTimestamp(const BufferItem &item) {
return timeUs;
}
-status_t GraphicBufferSource::submitBuffer_l(
- const BufferItem &item, int cbi) {
+status_t GraphicBufferSource::submitBuffer_l(const BufferItem &item, int cbi) {
ALOGV("submitBuffer_l cbi=%d", cbi);
int64_t timeUs = getTimestamp(item);
@@ -704,7 +709,8 @@ status_t GraphicBufferSource::submitBuffer_l(
OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader;
sp<GraphicBuffer> buffer = codecBuffer.mGraphicBuffer;
status_t err = mNodeInstance->emptyGraphicBuffer(
- header, buffer, OMX_BUFFERFLAG_ENDOFFRAME, timeUs);
+ header, buffer, OMX_BUFFERFLAG_ENDOFFRAME, timeUs,
+ item.mFence->isValid() ? item.mFence->dup() : -1);
if (err != OK) {
ALOGW("WARNING: emptyNativeWindowBuffer failed: 0x%x", err);
codecBuffer.mGraphicBuffer = NULL;
@@ -737,7 +743,7 @@ void GraphicBufferSource::submitEndOfInputStream_l() {
OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader;
status_t err = mNodeInstance->emptyGraphicBuffer(
header, NULL /* buffer */, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS,
- 0 /* timestamp */);
+ 0 /* timestamp */, -1 /* fenceFd */);
if (err != OK) {
ALOGW("emptyDirectBuffer EOS failed: 0x%x", err);
} else {
@@ -799,7 +805,7 @@ void GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) {
mConsumer->detachBuffer(item.mBuf);
mConsumer->attachBuffer(&item.mBuf, item.mGraphicBuffer);
mConsumer->releaseBuffer(item.mBuf, 0,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
+ EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
} else {
mConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 21ee96a..555bbec 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -93,7 +93,7 @@ public:
// Called from OnEmptyBufferDone. If we have a BQ buffer available,
// fill it with a new frame of data; otherwise, just mark it as available.
- void codecBufferEmptied(OMX_BUFFERHEADERTYPE* header);
+ void codecBufferEmptied(OMX_BUFFERHEADERTYPE* header, int fenceFd);
// Called when omx_message::FILL_BUFFER_DONE is received. (Currently the
// buffer source will fix timestamp in the header if needed.)
@@ -274,6 +274,7 @@ private:
int mLatestBufferId;
uint64_t mLatestBufferFrameNum;
int32_t mLatestBufferUseCount;
+ sp<Fence> mLatestBufferFence;
// The previous buffer should've been repeated but
// no codec buffer was available at the time.
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 4ca827c..76217ec 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -415,17 +415,17 @@ status_t OMX::freeBuffer(node_id node, OMX_U32 port_index, buffer_id buffer) {
port_index, buffer);
}
-status_t OMX::fillBuffer(node_id node, buffer_id buffer) {
- return findInstance(node)->fillBuffer(buffer);
+status_t OMX::fillBuffer(node_id node, buffer_id buffer, int fenceFd) {
+ return findInstance(node)->fillBuffer(buffer, fenceFd);
}
status_t OMX::emptyBuffer(
node_id node,
buffer_id buffer,
OMX_U32 range_offset, OMX_U32 range_length,
- OMX_U32 flags, OMX_TICKS timestamp) {
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
return findInstance(node)->emptyBuffer(
- buffer, range_offset, range_length, flags, timestamp);
+ buffer, range_offset, range_length, flags, timestamp, fenceFd);
}
status_t OMX::getExtensionIndex(
@@ -459,6 +459,7 @@ OMX_ERRORTYPE OMX::OnEvent(
omx_message msg;
msg.type = omx_message::EVENT;
msg.node = node;
+ msg.fenceFd = -1;
msg.u.event_data.event = eEvent;
msg.u.event_data.data1 = nData1;
msg.u.event_data.data2 = nData2;
@@ -469,12 +470,13 @@ OMX_ERRORTYPE OMX::OnEvent(
}
OMX_ERRORTYPE OMX::OnEmptyBufferDone(
- node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
+ node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer, int fenceFd) {
ALOGV("OnEmptyBufferDone buffer=%p", pBuffer);
omx_message msg;
msg.type = omx_message::EMPTY_BUFFER_DONE;
msg.node = node;
+ msg.fenceFd = fenceFd;
msg.u.buffer_data.buffer = buffer;
findDispatcher(node)->post(msg);
@@ -483,12 +485,13 @@ OMX_ERRORTYPE OMX::OnEmptyBufferDone(
}
OMX_ERRORTYPE OMX::OnFillBufferDone(
- node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
+ node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer, int fenceFd) {
ALOGV("OnFillBufferDone buffer=%p", pBuffer);
omx_message msg;
msg.type = omx_message::FILL_BUFFER_DONE;
msg.node = node;
+ msg.fenceFd = fenceFd;
msg.u.extended_buffer_data.buffer = buffer;
msg.u.extended_buffer_data.range_offset = pBuffer->nOffset;
msg.u.extended_buffer_data.range_length = pBuffer->nFilledLen;
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index e4b2de4..4ba4aeb 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -76,11 +76,11 @@ static const OMX_U32 kPortIndexOutput = 1;
#define SIMPLE_NEW_BUFFER(buffer_id, port, size, data) \
NEW_BUFFER_FMT(buffer_id, port, "%zu@%p", (size), (data))
-#define EMPTY_BUFFER(addr, header) "%#x [%u@%p]", \
- (addr), (header)->nAllocLen, (header)->pBuffer
-#define FULL_BUFFER(addr, header) "%#" PRIxPTR " [%u@%p (%u..+%u) f=%x ts=%lld]", \
+#define EMPTY_BUFFER(addr, header, fenceFd) "%#x [%u@%p fc=%d]", \
+ (addr), (header)->nAllocLen, (header)->pBuffer, (fenceFd)
+#define FULL_BUFFER(addr, header, fenceFd) "%#" PRIxPTR " [%u@%p (%u..+%u) f=%x ts=%lld fc=%d]", \
(intptr_t)(addr), (header)->nAllocLen, (header)->pBuffer, \
- (header)->nOffset, (header)->nFilledLen, (header)->nFlags, (header)->nTimeStamp
+ (header)->nOffset, (header)->nFilledLen, (header)->nFlags, (header)->nTimeStamp, (fenceFd)
#define WITH_STATS_WRAPPER(fmt, ...) fmt " { IN=%zu/%zu OUT=%zu/%zu }", ##__VA_ARGS__, \
mInputBuffersWithCodec.size(), mNumPortBuffers[kPortIndexInput], \
@@ -1050,7 +1050,7 @@ status_t OMXNodeInstance::freeBuffer(
return StatusFromOMXError(err);
}
-status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
+status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer, int fenceFd) {
Mutex::Autolock autoLock(mLock);
OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
@@ -1058,15 +1058,22 @@ status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
header->nOffset = 0;
header->nFlags = 0;
+ // meta now owns fenceFd
+ status_t res = storeFenceInMeta_l(header, fenceFd, kPortIndexOutput);
+ if (res != OK) {
+ CLOG_ERROR(fillBuffer::storeFenceInMeta, res, EMPTY_BUFFER(buffer, header, fenceFd));
+ return res;
+ }
+
{
Mutex::Autolock _l(mDebugLock);
mOutputBuffersWithCodec.add(header);
- CLOG_BUMPED_BUFFER(fillBuffer, WITH_STATS(EMPTY_BUFFER(buffer, header)));
+ CLOG_BUMPED_BUFFER(fillBuffer, WITH_STATS(EMPTY_BUFFER(buffer, header, fenceFd)));
}
OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
if (err != OMX_ErrorNone) {
- CLOG_ERROR(fillBuffer, err, EMPTY_BUFFER(buffer, header));
+ CLOG_ERROR(fillBuffer, err, EMPTY_BUFFER(buffer, header, fenceFd));
Mutex::Autolock _l(mDebugLock);
mOutputBuffersWithCodec.remove(header);
}
@@ -1076,7 +1083,7 @@ status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
status_t OMXNodeInstance::emptyBuffer(
OMX::buffer_id buffer,
OMX_U32 rangeOffset, OMX_U32 rangeLength,
- OMX_U32 flags, OMX_TICKS timestamp) {
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
Mutex::Autolock autoLock(mLock);
OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
@@ -1084,6 +1091,9 @@ status_t OMXNodeInstance::emptyBuffer(
// corner case: we permit rangeOffset == end-of-buffer with rangeLength == 0.
if (rangeOffset > header->nAllocLen
|| rangeLength > header->nAllocLen - rangeOffset) {
+ if (fenceFd >= 0) {
+ ::close(fenceFd);
+ }
return BAD_VALUE;
}
header->nFilledLen = rangeLength;
@@ -1110,7 +1120,7 @@ status_t OMXNodeInstance::emptyBuffer(
buffer_meta->CopyToOMX(header);
}
- return emptyBuffer_l(header, flags, timestamp, (intptr_t)buffer);
+ return emptyBuffer_l(header, flags, timestamp, (intptr_t)buffer, fenceFd);
}
// log queued buffer activity for the next few input and/or output frames
@@ -1137,11 +1147,62 @@ void OMXNodeInstance::unbumpDebugLevel_l(size_t portIndex) {
}
}
+status_t OMXNodeInstance::storeFenceInMeta_l(
+ OMX_BUFFERHEADERTYPE *header, int fenceFd, OMX_U32 portIndex) {
+ // propagate fence if component supports it; wait for it otherwise
+ OMX_U32 metaSize = portIndex == kPortIndexInput ? header->nFilledLen : header->nAllocLen;
+ if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer
+ && metaSize >= sizeof(VideoNativeMetadata)) {
+ VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)(header->pBuffer);
+ if (nativeMeta.nFenceFd >= 0) {
+ ALOGE("fence (%d) already exists in meta", nativeMeta.nFenceFd);
+ if (fenceFd >= 0) {
+ ::close(fenceFd);
+ }
+ return ALREADY_EXISTS;
+ }
+ nativeMeta.nFenceFd = fenceFd;
+ } else if (fenceFd >= 0) {
+ CLOG_BUFFER(storeFenceInMeta, "waiting for fence %d", fenceFd);
+ sp<Fence> fence = new Fence(fenceFd);
+ return fence->wait(IOMX::kFenceTimeoutMs);
+ }
+ return OK;
+}
+
+int OMXNodeInstance::retrieveFenceFromMeta_l(
+ OMX_BUFFERHEADERTYPE *header, OMX_U32 portIndex) {
+ OMX_U32 metaSize = portIndex == kPortIndexInput ? header->nAllocLen : header->nFilledLen;
+ int fenceFd = -1;
+ if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer
+ && header->nAllocLen >= sizeof(VideoNativeMetadata)) {
+ VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)(header->pBuffer);
+ if (nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
+ fenceFd = nativeMeta.nFenceFd;
+ nativeMeta.nFenceFd = -1;
+ }
+ if (metaSize < sizeof(nativeMeta) && fenceFd >= 0) {
+ CLOG_ERROR(foundFenceInEmptyMeta, BAD_VALUE, FULL_BUFFER(
+ NULL, header, nativeMeta.nFenceFd));
+ fenceFd = -1;
+ }
+ }
+ return fenceFd;
+}
+
status_t OMXNodeInstance::emptyBuffer_l(
- OMX_BUFFERHEADERTYPE *header, OMX_U32 flags, OMX_TICKS timestamp, intptr_t debugAddr) {
+ OMX_BUFFERHEADERTYPE *header, OMX_U32 flags, OMX_TICKS timestamp,
+ intptr_t debugAddr, int fenceFd) {
header->nFlags = flags;
header->nTimeStamp = timestamp;
+ status_t res = storeFenceInMeta_l(header, fenceFd, kPortIndexInput);
+ if (res != OK) {
+ CLOG_ERROR(emptyBuffer::storeFenceInMeta, res, WITH_STATS(
+ FULL_BUFFER(debugAddr, header, fenceFd)));
+ return res;
+ }
+
{
Mutex::Autolock _l(mDebugLock);
mInputBuffersWithCodec.add(header);
@@ -1151,11 +1212,11 @@ status_t OMXNodeInstance::emptyBuffer_l(
bumpDebugLevel_l(2 /* numInputBuffers */, 0 /* numOutputBuffers */);
}
- CLOG_BUMPED_BUFFER(emptyBuffer, WITH_STATS(FULL_BUFFER(debugAddr, header)));
+ CLOG_BUMPED_BUFFER(emptyBuffer, WITH_STATS(FULL_BUFFER(debugAddr, header, fenceFd)));
}
OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
- CLOG_IF_ERROR(emptyBuffer, err, FULL_BUFFER(debugAddr, header));
+ CLOG_IF_ERROR(emptyBuffer, err, FULL_BUFFER(debugAddr, header, fenceFd));
{
Mutex::Autolock _l(mDebugLock);
@@ -1172,18 +1233,19 @@ status_t OMXNodeInstance::emptyBuffer_l(
// like emptyBuffer, but the data is already in header->pBuffer
status_t OMXNodeInstance::emptyGraphicBuffer(
OMX_BUFFERHEADERTYPE *header, const sp<GraphicBuffer> &graphicBuffer,
- OMX_U32 flags, OMX_TICKS timestamp) {
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
Mutex::Autolock autoLock(mLock);
OMX::buffer_id buffer = findBufferID(header);
status_t err = updateGraphicBufferInMeta_l(kPortIndexInput, graphicBuffer, buffer, header);
if (err != OK) {
- CLOG_ERROR(emptyGraphicBuffer, err, FULL_BUFFER((intptr_t)header->pBuffer, header));
+ CLOG_ERROR(emptyGraphicBuffer, err, FULL_BUFFER(
+ (intptr_t)header->pBuffer, header, fenceFd));
return err;
}
header->nOffset = 0;
header->nFilledLen = graphicBuffer == NULL ? 0 : header->nAllocLen;
- return emptyBuffer_l(header, flags, timestamp, (intptr_t)header->pBuffer);
+ return emptyBuffer_l(header, flags, timestamp, (intptr_t)header->pBuffer, fenceFd);
}
status_t OMXNodeInstance::getExtensionIndex(
@@ -1307,7 +1369,8 @@ void OMXNodeInstance::onMessage(const omx_message &msg) {
mOutputBuffersWithCodec.remove(buffer);
CLOG_BUMPED_BUFFER(
- FBD, WITH_STATS(FULL_BUFFER(msg.u.extended_buffer_data.buffer, buffer)));
+ FBD, WITH_STATS(FULL_BUFFER(
+ msg.u.extended_buffer_data.buffer, buffer, msg.fenceFd)));
unbumpDebugLevel_l(kPortIndexOutput);
}
@@ -1335,7 +1398,7 @@ void OMXNodeInstance::onMessage(const omx_message &msg) {
mInputBuffersWithCodec.remove(buffer);
CLOG_BUMPED_BUFFER(
- EBD, WITH_STATS(EMPTY_BUFFER(msg.u.buffer_data.buffer, buffer)));
+ EBD, WITH_STATS(EMPTY_BUFFER(msg.u.buffer_data.buffer, buffer, msg.fenceFd)));
}
if (bufferSource != NULL) {
@@ -1344,7 +1407,7 @@ void OMXNodeInstance::onMessage(const omx_message &msg) {
// Don't dispatch a message back to ACodec, since it doesn't
// know that anyone asked to have the buffer emptied and will
// be very confused.
- bufferSource->codecBufferEmptied(buffer);
+ bufferSource->codecBufferEmptied(buffer, msg.fenceFd);
return;
}
}
@@ -1439,8 +1502,9 @@ OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
if (instance->mDying) {
return OMX_ErrorNone;
}
+ int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput);
return instance->owner()->OnEmptyBufferDone(instance->nodeID(),
- instance->findBufferID(pBuffer), pBuffer);
+ instance->findBufferID(pBuffer), pBuffer, fenceFd);
}
// static
@@ -1452,8 +1516,9 @@ OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
if (instance->mDying) {
return OMX_ErrorNone;
}
+ int fenceFd = instance->retrieveFenceFromMeta_l(pBuffer, kPortIndexOutput);
return instance->owner()->OnFillBufferDone(instance->nodeID(),
- instance->findBufferID(pBuffer), pBuffer);
+ instance->findBufferID(pBuffer), pBuffer, fenceFd);
}
void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
index 5f80cbc..cd1ac36 100644
--- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
@@ -517,6 +517,16 @@ const uint8_t *SoftVideoEncoderOMXComponent::extractGraphicBuffer(
// TODO do we need to support other formats?
srcStride *= 4;
}
+
+ if (nativeMeta.nFenceFd >= 0) {
+ sp<Fence> fence = new Fence(nativeMeta.nFenceFd);
+ nativeMeta.nFenceFd = -1;
+ status_t err = fence->wait(IOMX::kFenceTimeoutMs);
+ if (err != OK) {
+ ALOGE("Timed out waiting on input fence");
+ return NULL;
+ }
+ }
} else {
// TODO: remove this part. Check if anyone uses this.