MediaCodec refactoring part 1-c: buffer ownership
- Buffers are (roughly) owned by themselves.
- As a corollary, remove output format change related events
and replace by inspecting formats associated with each buffers.
Bug: 32133435
Test: gts-tradefed run gts -m GtsExoPlayerTestCases
Test: (manual) Run Play Movies app to play a secure content.
Change-Id: I6b57da61c2d71acd0d5be4281de823ba1c95b72f
diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp
index 1a4bf08..8fe1dd4 100644
--- a/cmds/stagefright/sf2.cpp
+++ b/cmds/stagefright/sf2.cpp
@@ -230,7 +230,6 @@
mCodec->signalResume();
(new AMessage(kWhatSeek, this))->post(5000000ll);
- } else if (what == CodecBase::kWhatOutputFormatChanged) {
} else if (what == CodecBase::kWhatShutdownCompleted) {
mDecodeLooper->unregisterHandler(mCodec->id());
diff --git a/include/media/MediaCodecBuffer.h b/include/media/MediaCodecBuffer.h
index 2df81dd..05aaa14 100644
--- a/include/media/MediaCodecBuffer.h
+++ b/include/media/MediaCodecBuffer.h
@@ -58,6 +58,8 @@
sp<AMessage> meta();
sp<AMessage> format();
+ virtual sp<MediaCodecBuffer> clone(const sp<AMessage> &format);
+
private:
MediaCodecBuffer() = delete;
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index cdfe2c9..64a542d 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -81,7 +81,7 @@
friend struct ACodec;
Vector<IOMX::buffer_id> mBufferIDs;
- Vector<sp<MediaCodecBuffer>> mBuffers;
+ Vector<sp<MediaCodecBuffer> > mBuffers;
PortDescription();
void addBuffer(IOMX::buffer_id id, const sp<MediaCodecBuffer> &buffer);
@@ -188,7 +188,6 @@
sp<RefBase> mCodecRef; // and a reference to the IMemory
sp<GraphicBuffer> mGraphicBuffer;
- sp<NativeHandle> mNativeHandle;
int mFenceFd;
FrameRenderTracker::Info *mRenderInfo;
@@ -200,8 +199,6 @@
// Log error, if the current fence is not a read/write fence.
void checkReadFence(const char *dbg);
void checkWriteFence(const char *dbg);
-
- sp<MediaCodecBuffer> alloc(const sp<AMessage> &format);
};
static const char *_asString(BufferInfo::Status s);
diff --git a/include/media/stagefright/CodecBase.h b/include/media/stagefright/CodecBase.h
index 1295b59..d8c43a4 100644
--- a/include/media/stagefright/CodecBase.h
+++ b/include/media/stagefright/CodecBase.h
@@ -45,7 +45,6 @@
kWhatEOS = 'eos ',
kWhatShutdownCompleted = 'scom',
kWhatFlushCompleted = 'fcom',
- kWhatOutputFormatChanged = 'outC',
kWhatError = 'erro',
kWhatComponentAllocated = 'cAll',
kWhatComponentConfigured = 'cCon',
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 19d7047..2c31a0d 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -246,7 +246,7 @@
kFlagIsSecure = 64,
kFlagSawMediaServerDie = 128,
kFlagIsEncoder = 256,
- kFlagGatherCodecSpecificData = 512,
+ // 512 skipped
kFlagIsAsync = 1024,
kFlagIsComponentAllocated = 2048,
kFlagPushBlankBuffersOnShutdown = 4096,
@@ -258,7 +258,6 @@
sp<MediaCodecBuffer> mSecureData;
sp<IMemory> mSharedEncryptedBuffer;
sp<AMessage> mNotify;
- sp<AMessage> mFormat;
bool mOwnedByClient;
};
@@ -329,6 +328,7 @@
List<size_t> mAvailPortBuffers[2];
Vector<BufferInfo> mPortBuffers[2];
+ Vector<sp<MediaCodecBuffer>> mPortBufferArrays[2];
int32_t mDequeueInputTimeoutGeneration;
sp<AReplyToken> mDequeueInputReplyID;
diff --git a/include/media/stagefright/MediaFilter.h b/include/media/stagefright/MediaFilter.h
index 6aa87e8..0e39431 100644
--- a/include/media/stagefright/MediaFilter.h
+++ b/include/media/stagefright/MediaFilter.h
@@ -144,7 +144,6 @@
void postFillThisBuffer(BufferInfo *info);
void postDrainThisBuffer(BufferInfo *info);
void postEOS();
- void sendFormatChange();
void requestFillEmptyInput();
void processBuffers();
diff --git a/media/libmedia/MediaCodecBuffer.cpp b/media/libmedia/MediaCodecBuffer.cpp
index 2d255be..2af31d0 100644
--- a/media/libmedia/MediaCodecBuffer.cpp
+++ b/media/libmedia/MediaCodecBuffer.cpp
@@ -80,4 +80,8 @@
return mFormat;
}
+sp<MediaCodecBuffer> MediaCodecBuffer::clone(const sp<AMessage> &format) {
+ return new MediaCodecBuffer(format, mBuffer);
+}
+
} // namespace android
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index ed29859..52c0feb 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -866,7 +866,8 @@
size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize);
mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
- const sp<AMessage> &format = portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
+ const sp<AMessage> &format =
+ portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
if (mem == NULL || mem->pointer() == NULL) {
@@ -1478,20 +1479,20 @@
if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
VideoGrallocMetadata *grallocMeta =
- reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->data());
+ reinterpret_cast<VideoGrallocMetadata *>(oldest->mCodecData->base());
ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
(unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
mDequeueCounter - oldest->mDequeuedAt,
(void *)(uintptr_t)grallocMeta->pHandle,
- oldest->mGraphicBuffer->handle, oldest->mData->data());
+ oldest->mGraphicBuffer->handle, oldest->mCodecData->base());
} else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
VideoNativeMetadata *nativeMeta =
- reinterpret_cast<VideoNativeMetadata *>(oldest->mData->data());
+ reinterpret_cast<VideoNativeMetadata *>(oldest->mCodecData->base());
ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
(unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
mDequeueCounter - oldest->mDequeuedAt,
(void *)(uintptr_t)nativeMeta->pBuffer,
- oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->data());
+ oldest->mGraphicBuffer->getNativeBuffer(), oldest->mCodecData->base());
}
updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
@@ -1541,9 +1542,9 @@
// there should not be any fences in the metadata
MetadataBufferType type =
portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
- if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL
- && info->mData->size() >= sizeof(VideoNativeMetadata)) {
- int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd;
+ if (type == kMetadataBufferTypeANWBuffer && info->mCodecData != NULL
+ && info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
+ int fenceFd = ((VideoNativeMetadata *)info->mCodecData->base())->nFenceFd;
if (fenceFd >= 0) {
ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
@@ -2190,7 +2191,6 @@
// NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame.
mBaseOutputFormat = outputFormat;
- // trigger a kWhatOutputFormatChanged msg on first buffer
mLastOutputFormat.clear();
err = getPortFormat(kPortIndexInput, inputFormat);
@@ -5188,11 +5188,6 @@
mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
}
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatOutputFormatChanged);
- notify->setMessage("format", mOutputFormat);
- notify->post();
-
// mLastOutputFormat is not used when tunneled; doing this just to stay consistent
mLastOutputFormat = mOutputFormat;
}
@@ -5572,8 +5567,8 @@
notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
notify->setInt32("buffer-id", info->mBufferID);
- info->mData->meta()->clear();
- notify->setObject("buffer", info->mData);
+ notify->setObject("buffer", info->mData->clone(mCodec->mInputFormat));
+ info->mData.clear();
sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
reply->setInt32("buffer-id", info->mBufferID);
@@ -5606,8 +5601,6 @@
mCodec->mComponentName.c_str(), err);
eos = true;
}
-
- buffer.clear();
} else {
buffer = static_cast<MediaCodecBuffer *>(obj.get());
}
@@ -5628,6 +5621,7 @@
}
info->mStatus = BufferInfo::OWNED_BY_US;
+ info->mData = buffer;
switch (mode) {
case KEEP_BUFFERS:
@@ -5672,11 +5666,12 @@
flags |= OMX_BUFFERFLAG_EOS;
}
- if (buffer != info->mCodecData) {
+ size_t size = buffer->size();
+ if (buffer->base() != info->mCodecData->base()) {
ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
mCodec->mComponentName.c_str(),
bufferID,
- buffer.get(), info->mCodecData.get());
+ buffer->base(), info->mCodecData->base());
sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
if (converter == NULL || isCSD) {
@@ -5687,6 +5682,7 @@
mCodec->signalError(OMX_ErrorUndefined, err);
return;
}
+ size = info->mCodecData->size();
}
if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
@@ -5763,7 +5759,7 @@
err2 = mCodec->mOMXNode->emptyBuffer(
bufferID,
0,
- info->mCodecData->size(),
+ size,
flags,
timeUs,
info->mFenceFd);
@@ -5774,6 +5770,8 @@
return;
}
info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
+ // Hold the reference while component is using the buffer.
+ info->mData = buffer;
if (!eos && err == OK) {
getMoreInputDataIfPossible();
@@ -5940,7 +5938,7 @@
sp<AMessage> reply =
new AMessage(kWhatOutputBufferDrained, mCodec);
- sp<MediaCodecBuffer> buffer = info->mData;
+ sp<MediaCodecBuffer> buffer = info->mData->clone(mCodec->mOutputFormat);
if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
// pretend that output format has changed on the first frame (we used to do this)
@@ -5971,7 +5969,7 @@
buffer->meta()->setPointer("handle", handle);
buffer->meta()->setInt32("rangeOffset", rangeOffset);
buffer->meta()->setInt32("rangeLength", rangeLength);
- } else if (buffer == info->mCodecData) {
+ } else if (buffer->base() == info->mCodecData->base()) {
buffer->setRange(rangeOffset, rangeLength);
} else {
info->mCodecData->setRange(rangeOffset, rangeLength);
@@ -6000,6 +5998,7 @@
notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
notify->setInt32("buffer-id", info->mBufferID);
notify->setObject("buffer", buffer);
+ info->mData.clear();
notify->setInt32("flags", flags);
reply->setInt32("buffer-id", info->mBufferID);
@@ -6056,6 +6055,7 @@
mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
return;
}
+ info->mData = buffer;
android_native_rect_t crop;
if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)
diff --git a/media/libstagefright/BufferImpl.cpp b/media/libstagefright/BufferImpl.cpp
index 4ed7911..81fe0fe 100644
--- a/media/libstagefright/BufferImpl.cpp
+++ b/media/libstagefright/BufferImpl.cpp
@@ -34,7 +34,11 @@
mMemory(mem) {
}
-SecureBuffer::SecureBuffer(const sp<AMessage> &format, void *ptr, size_t size)
+sp<MediaCodecBuffer> SharedMemoryBuffer::clone(const sp<AMessage> &format) {
+ return new SharedMemoryBuffer(format, mMemory);
+}
+
+SecureBuffer::SecureBuffer(const sp<AMessage> &format, const void *ptr, size_t size)
: MediaCodecBuffer(format, new ABuffer(nullptr, size)),
mPointer(ptr) {
}
@@ -46,6 +50,12 @@
mHandle(handle) {
}
+sp<MediaCodecBuffer> SecureBuffer::clone(const sp<AMessage> &format) {
+ return (mHandle == nullptr)
+ ? new SecureBuffer(format, mPointer, capacity())
+ : new SecureBuffer(format, mHandle, capacity());
+}
+
void *SecureBuffer::getDestinationPointer() {
return (void *)(mHandle == nullptr ? mPointer : mHandle->handle());
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 5ab5f3e..12eca10 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -929,9 +929,8 @@
return INVALID_OPERATION;
}
- // by the time buffers array is initialized, crypto is set
*buffer = info.mData;
- *format = info.mFormat;
+ *format = info.mData->format();
return OK;
}
@@ -1323,6 +1322,7 @@
|| portIndex == kPortIndexOutput);
mPortBuffers[portIndex].clear();
+ mPortBufferArrays[portIndex].clear();
Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
@@ -1333,32 +1333,12 @@
static_cast<CodecBase::PortDescription *>(obj.get());
size_t numBuffers = portDesc->countBuffers();
-
- size_t totalSize = 0;
- for (size_t i = 0; i < numBuffers; ++i) {
- if (portIndex == kPortIndexInput && mCrypto != NULL) {
- totalSize += portDesc->bufferAt(i)->capacity();
- }
- }
-
- if (totalSize) {
- mDealer = new MemoryDealer(totalSize, "MediaCodec");
- }
-
for (size_t i = 0; i < numBuffers; ++i) {
BufferInfo info;
info.mBufferID = portDesc->bufferIDAt(i);
info.mOwnedByClient = false;
- info.mData = portDesc->bufferAt(i);
-
- if (portIndex == kPortIndexInput && mCrypto != NULL) {
- sp<IMemory> mem = mDealer->allocate(info.mData->capacity());
- info.mSecureData = info.mData;
- info.mData = new SharedMemoryBuffer(mInputFormat, mem);
- info.mSharedEncryptedBuffer = mem;
- }
-
buffers->push_back(info);
+ mPortBufferArrays[portIndex].push_back(portDesc->bufferAt(i));
}
if (portIndex == kPortIndexOutput) {
@@ -1382,62 +1362,6 @@
break;
}
- case CodecBase::kWhatOutputFormatChanged:
- {
- CHECK(msg->findMessage("format", &mOutputFormat));
-
- ALOGV("[%s] output format changed to: %s",
- mComponentName.c_str(), mOutputFormat->debugString(4).c_str());
-
- if (mSoftRenderer == NULL &&
- mSurface != NULL &&
- (mFlags & kFlagUsesSoftwareRenderer)) {
- AString mime;
- CHECK(mOutputFormat->findString("mime", &mime));
-
- // TODO: propagate color aspects to software renderer to allow better
- // color conversion to RGB. For now, just mark dataspace for YUV
- // rendering.
- int32_t dataSpace;
- if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
- ALOGD("[%s] setting dataspace on output surface to #%x",
- mComponentName.c_str(), dataSpace);
- int err = native_window_set_buffers_data_space(
- mSurface.get(), (android_dataspace)dataSpace);
- ALOGW_IF(err != 0, "failed to set dataspace on surface (%d)", err);
- }
-
- if (mime.startsWithIgnoreCase("video/")) {
- mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees);
- }
- }
-
- if (mFlags & kFlagIsEncoder) {
- // Before we announce the format change we should
- // collect codec specific data and amend the output
- // format as necessary.
- mFlags |= kFlagGatherCodecSpecificData;
- } else if (mFlags & kFlagIsAsync) {
- onOutputFormatChanged();
- } else {
- mFlags |= kFlagOutputFormatChanged;
- postActivityNotificationIfPossible();
- }
-
- // Notify mCrypto of video resolution changes
- if (mCrypto != NULL) {
- int32_t left, top, right, bottom, width, height;
- if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
- mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
- } else if (mOutputFormat->findInt32("width", &width)
- && mOutputFormat->findInt32("height", &height)) {
- mCrypto->notifyResolution(width, height);
- }
- }
-
- break;
- }
-
case CodecBase::kWhatOutputFramesRendered:
{
// ignore these in all states except running, and check that we have a
@@ -1528,27 +1452,65 @@
CHECK(msg->findInt32("flags", &omxFlags));
buffer->meta()->setInt32("omxFlags", omxFlags);
+ if (mOutputFormat != buffer->format()) {
+ mOutputFormat = buffer->format();
+ ALOGV("[%s] output format changed to: %s",
+ mComponentName.c_str(), mOutputFormat->debugString(4).c_str());
- if (mFlags & kFlagGatherCodecSpecificData) {
- // This is the very first output buffer after a
- // format change was signalled, it'll either contain
- // the one piece of codec specific data we can expect
- // or there won't be codec specific data.
- if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
- status_t err =
- amendOutputFormatWithCodecSpecificData(buffer);
+ if (mSoftRenderer == NULL &&
+ mSurface != NULL &&
+ (mFlags & kFlagUsesSoftwareRenderer)) {
+ AString mime;
+ CHECK(mOutputFormat->findString("mime", &mime));
- if (err != OK) {
- ALOGE("Codec spit out malformed codec "
- "specific data!");
+ // TODO: propagate color aspects to software renderer to allow better
+ // color conversion to RGB. For now, just mark dataspace for YUV
+ // rendering.
+ int32_t dataSpace;
+ if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
+ ALOGD("[%s] setting dataspace on output surface to #%x",
+ mComponentName.c_str(), dataSpace);
+ int err = native_window_set_buffers_data_space(
+ mSurface.get(), (android_dataspace)dataSpace);
+ ALOGW_IF(err != 0, "failed to set dataspace on surface (%d)", err);
+ }
+
+ if (mime.startsWithIgnoreCase("video/")) {
+ mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees);
}
}
- mFlags &= ~kFlagGatherCodecSpecificData;
+ if (mFlags & kFlagIsEncoder) {
+ // Before we announce the format change we should
+ // collect codec specific data and amend the output
+ // format as necessary.
+ if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ status_t err =
+ amendOutputFormatWithCodecSpecificData(buffer);
+
+ if (err != OK) {
+ ALOGE("Codec spit out malformed codec "
+ "specific data!");
+ }
+ }
+ }
+
if (mFlags & kFlagIsAsync) {
onOutputFormatChanged();
} else {
mFlags |= kFlagOutputFormatChanged;
+ postActivityNotificationIfPossible();
+ }
+
+ // Notify mCrypto of video resolution changes
+ if (mCrypto != NULL) {
+ int32_t left, top, right, bottom, width, height;
+ if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
+ mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
+ } else if (mOutputFormat->findInt32("width", &width)
+ && mOutputFormat->findInt32("height", &height)) {
+ mCrypto->notifyResolution(width, height);
+ }
}
}
@@ -2170,12 +2132,10 @@
// createInputSurface(), or persistent set by setInputSurface()),
// give the client an empty input buffers array.
if (portIndex != kPortIndexInput || !mHaveInputSurface) {
- const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
+ const Vector<sp<MediaCodecBuffer>> &srcBuffers = mPortBufferArrays[portIndex];
for (size_t i = 0; i < srcBuffers.size(); ++i) {
- const BufferInfo &info = srcBuffers.itemAt(i);
-
- dstBuffers->push_back(info.mData);
+ dstBuffers->push_back(srcBuffers[i]);
}
}
@@ -2345,7 +2305,6 @@
mFlags &= ~kFlagOutputBuffersChanged;
mFlags &= ~kFlagStickyError;
mFlags &= ~kFlagIsEncoder;
- mFlags &= ~kFlagGatherCodecSpecificData;
mFlags &= ~kFlagIsAsync;
mStickyError = OK;
@@ -2387,12 +2346,15 @@
if (info->mNotify != NULL) {
sp<AMessage> msg = info->mNotify;
info->mNotify = NULL;
+ msg->setObject("buffer", (portIndex == kPortIndexInput && mCrypto != NULL)
+ ? info->mSecureData : info->mData);
if (isReclaim && info->mOwnedByClient) {
ALOGD("port %d buffer %zu still owned by client when codec is reclaimed",
portIndex, i);
} else {
- // TODO: clear memory reference.
info->mOwnedByClient = false;
+ info->mData.clear();
+ info->mSecureData.clear();
}
if (portIndex == kPortIndexInput) {
@@ -2404,6 +2366,7 @@
}
mAvailPortBuffers[portIndex].clear();
+ mPortBufferArrays[portIndex].clear();
}
size_t MediaCodec::updateBuffers(
@@ -2412,8 +2375,22 @@
uint32_t bufferID;
CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
+ sp<RefBase> obj;
+ CHECK(msg->findObject("buffer", &obj));
+ sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
+ if (portIndex == kPortIndexInput && mCrypto != NULL && mDealer == NULL) {
+ // Lazy initialization for encrypted buffers.
+ size_t capacity = buffer->capacity();
+ size_t totalSize = capacity * buffers->size();
+
+ mDealer = new MemoryDealer(totalSize, "MediaCodec");
+ for (size_t i = 0; i < buffers->size(); ++i) {
+ BufferInfo *info = &buffers->editItemAt(i);
+ info->mSharedEncryptedBuffer = mDealer->allocate(capacity);
+ }
+ }
for (size_t i = 0; i < buffers->size(); ++i) {
BufferInfo *info = &buffers->editItemAt(i);
@@ -2422,8 +2399,13 @@
CHECK(info->mNotify == NULL);
CHECK(msg->findMessage("reply", &info->mNotify));
- info->mFormat =
- (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
+ if (portIndex == kPortIndexInput && mCrypto != NULL) {
+ info->mSecureData = buffer;
+ info->mData = new SharedMemoryBuffer(
+ buffer->format(), info->mSharedEncryptedBuffer);
+ } else {
+ info->mData = buffer;
+ }
mAvailPortBuffers[portIndex].push_back(i);
return i;
@@ -2556,13 +2538,14 @@
if (flags & BUFFER_FLAG_CODECCONFIG) {
buffer->meta()->setInt32("csd", true);
}
- // TODO: release buffer reference.
// synchronization boundary for getBufferAndFormat
{
Mutex::Autolock al(mBufferLock);
info->mOwnedByClient = false;
}
+ info->mData.clear();
+ info->mSecureData.clear();
reply->setObject("buffer", buffer);
reply->post();
@@ -2634,7 +2617,7 @@
if (mSoftRenderer != NULL) {
std::list<FrameRenderTracker::Info> doneFrames = mSoftRenderer->render(
info->mData->data(), info->mData->size(),
- mediaTimeUs, renderTimeNs, NULL, info->mFormat);
+ mediaTimeUs, renderTimeNs, NULL, info->mData->format());
// if we are running, notify rendered frames
if (!doneFrames.empty() && mState == STARTED && mOnFrameRenderedNotification != NULL) {
@@ -2649,7 +2632,7 @@
}
info->mNotify->setObject("buffer", info->mData);
- // TODO: release buffer reference.
+ info->mData.clear();
info->mNotify->post();
info->mNotify.clear();
@@ -2675,13 +2658,13 @@
info->mOwnedByClient = true;
// set image-data
- if (info->mFormat != NULL) {
+ if (info->mData->format() != NULL) {
sp<ABuffer> imageData;
- if (info->mFormat->findBuffer("image-data", &imageData)) {
+ if (info->mData->format()->findBuffer("image-data", &imageData)) {
info->mData->meta()->setBuffer("image-data", imageData);
}
int32_t left, top, right, bottom;
- if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
+ if (info->mData->format()->findRect("crop", &left, &top, &right, &bottom)) {
info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
}
}
diff --git a/media/libstagefright/filters/MediaFilter.cpp b/media/libstagefright/filters/MediaFilter.cpp
index f26c840..30e3643 100644
--- a/media/libstagefright/filters/MediaFilter.cpp
+++ b/media/libstagefright/filters/MediaFilter.cpp
@@ -360,25 +360,6 @@
ALOGV("Sent kWhatEOS.");
}
-void MediaFilter::sendFormatChange() {
- sp<AMessage> notify = mNotify->dup();
-
- notify->setInt32("what", kWhatOutputFormatChanged);
-
- AString mime;
- CHECK(mOutputFormat->findString("mime", &mime));
- notify->setString("mime", mime.c_str());
-
- notify->setInt32("stride", mStride);
- notify->setInt32("slice-height", mSliceHeight);
- notify->setInt32("color-format", mColorFormatOut);
- notify->setRect("crop", 0, 0, mStride - 1, mSliceHeight - 1);
- notify->setInt32("width", mWidth);
- notify->setInt32("height", mHeight);
-
- notify->post();
-}
-
void MediaFilter::requestFillEmptyInput() {
if (mPortEOS[kPortIndexInput]) {
return;
@@ -553,8 +534,6 @@
notify->post();
mState = CONFIGURED;
ALOGV("Handled kWhatConfigureComponent.");
-
- sendFormatChange();
}
void MediaFilter::onStart() {
diff --git a/media/libstagefright/include/SecureBuffer.h b/media/libstagefright/include/SecureBuffer.h
index 4bb1418..ac7399a 100644
--- a/media/libstagefright/include/SecureBuffer.h
+++ b/media/libstagefright/include/SecureBuffer.h
@@ -34,7 +34,7 @@
*/
class SecureBuffer : public MediaCodecBuffer {
public:
- SecureBuffer(const sp<AMessage> &format, void *ptr, size_t size);
+ SecureBuffer(const sp<AMessage> &format, const void *ptr, size_t size);
SecureBuffer(const sp<AMessage> &format, const sp<NativeHandle> &handle, size_t size);
virtual ~SecureBuffer() = default;
@@ -42,6 +42,8 @@
void *getDestinationPointer();
ICrypto::DestinationType getDestinationType();
+ virtual sp<MediaCodecBuffer> clone(const sp<AMessage> &format) override;
+
private:
SecureBuffer() = delete;
diff --git a/media/libstagefright/include/SharedMemoryBuffer.h b/media/libstagefright/include/SharedMemoryBuffer.h
index 1d7f7a6..c52e5c5 100644
--- a/media/libstagefright/include/SharedMemoryBuffer.h
+++ b/media/libstagefright/include/SharedMemoryBuffer.h
@@ -34,6 +34,8 @@
virtual ~SharedMemoryBuffer() = default;
+ virtual sp<MediaCodecBuffer> clone(const sp<AMessage> &format) override;
+
private:
SharedMemoryBuffer() = delete;