Codec2: pass block pools by ID
This highlighted a cfi bug so disabled cfi:
frameworks/av/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp:1237:15: runtime error:
control flow integrity check for type 'android::C2BlockPool' failed during virtual call
(vtable address 0x0078b2f659c0)
0x0078b2f659c0: note: invalid vtable in module /system/lib64/libstagefright_soft_c2avcdec.so
00 00 00 00 98 a8 ef b2 78 00 00 00 f0 df f3 b2 78 00 00 00 00 e0 f3 b2 78 00 00 00 00 e0 f3 b2
^
Bug: 64121714
Test: unittest
Change-Id: I25d9c9d603e78c5043568cfb951d26aacea798a4
diff --git a/media/libstagefright/codec2/Android.bp b/media/libstagefright/codec2/Android.bp
index f79e058..311a20b 100644
--- a/media/libstagefright/codec2/Android.bp
+++ b/media/libstagefright/codec2/Android.bp
@@ -17,9 +17,9 @@
"unsigned-integer-overflow",
"signed-integer-overflow",
],
- cfi: true,
+ cfi: false, // true,
diag: {
- cfi: true,
+ cfi: false, // true,
},
},
diff --git a/media/libstagefright/codec2/include/C2Config.h b/media/libstagefright/codec2/include/C2Config.h
index d4294c4..0568432 100644
--- a/media/libstagefright/codec2/include/C2Config.h
+++ b/media/libstagefright/codec2/include/C2Config.h
@@ -61,13 +61,15 @@
kParamIndexMime,
kParamIndexStreamCount,
kParamIndexFormat,
+ kParamIndexBlockPools,
+
+ kParamIndexMaxVideoSizeHint,
+ kParamIndexVideoSizeTuning,
// video info
kParamIndexStructStart = 0x1,
kParamIndexVideoSize,
- kParamIndexMaxVideoSizeHint,
- kParamIndexVideoSizeTuning,
kParamIndexParamStart = 0x800,
};
@@ -125,6 +127,8 @@
typedef C2StreamParam<C2Tuning, C2Uint32Value, kParamIndexFormat> C2StreamFormatConfig;
+typedef C2PortParam<C2Tuning, C2Uint64Array, kParamIndexBlockPools> C2PortBlockPoolsTuning;
+
/*
Component description fields:
diff --git a/media/libstagefright/codec2/vndk/C2Store.cpp b/media/libstagefright/codec2/vndk/C2Store.cpp
index 8413484..f8ddfef 100644
--- a/media/libstagefright/codec2/vndk/C2Store.cpp
+++ b/media/libstagefright/codec2/vndk/C2Store.cpp
@@ -16,6 +16,7 @@
#include <C2AllocatorGralloc.h>
#include <C2AllocatorIon.h>
+#include <C2BufferPriv.h>
#include <C2Component.h>
#include <C2PlatformSupport.h>
@@ -109,4 +110,35 @@
return std::make_shared<C2PlatformAllocatorStore>();
}
+C2Status GetCodec2BlockPool(
+ C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool) {
+ pool->reset();
+ if (!component) {
+ return C2_BAD_VALUE;
+ }
+ // TODO support pre-registered block pools
+ std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
+ std::shared_ptr<C2Allocator> allocator;
+ C2Status res = C2_NOT_FOUND;
+
+ switch (id) {
+ case C2BlockPool::BASIC_LINEAR:
+ res = allocatorStore->getAllocator(C2AllocatorStore::DEFAULT_LINEAR, &allocator);
+ if (res == OK) {
+ *pool = std::make_shared<C2BasicLinearBlockPool>(allocator);
+ }
+ break;
+ case C2BlockPool::BASIC_GRAPHIC:
+ res = allocatorStore->getAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
+ if (res == OK) {
+ *pool = std::make_shared<C2BasicGraphicBlockPool>(allocator);
+ }
+ break;
+ default:
+ break;
+ }
+ return res;
+}
+
} // namespace android
\ No newline at end of file
diff --git a/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h b/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
index 9402050..40bb548 100644
--- a/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
+++ b/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
@@ -25,9 +25,33 @@
/**
* Returns the platform allocator store.
+ * \retval nullptr if the platform allocator store could not be obtained
*/
std::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore();
+/**
+ * Retrieves a block pool for a component.
+ *
+ * \param id the local ID of the block pool
+ * \param component the component using the block pool (must be non-null)
+ * \param pool pointer to where the obtained block pool shall be stored on success. nullptr
+ * will be stored here on failure
+ *
+ * \retval C2_OK the operation was successful
+ * \retval C2_BAD_VALUE the component is null
+ * \retval C2_NOT_FOUND if the block pool does not exist
+ * \retval C2_NO_MEMORY not enough memory to fetch the block pool (this return value is only
+ * possible for basic pools)
+ * \retval C2_TIMED_OUT the operation timed out (this return value is only possible for basic pools)
+ * \retval C2_REFUSED no permission to complete any required allocation (this return value is only
+ * possible for basic pools)
+ * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected,
+ * this return value is only possible for basic pools)
+ */
+C2Status GetCodec2BlockPool(
+ C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
+ std::shared_ptr<C2BlockPool> *pool);
+
} // namespace android
#endif // STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
diff --git a/media/libstagefright/codecs/avcdec/Android.bp b/media/libstagefright/codecs/avcdec/Android.bp
index 3b2602d..5dcffd5 100644
--- a/media/libstagefright/codecs/avcdec/Android.bp
+++ b/media/libstagefright/codecs/avcdec/Android.bp
@@ -74,9 +74,9 @@
misc_undefined: [
"signed-integer-overflow",
],
- cfi: true,
+ cfi: false, // true,
diag: {
- cfi: true,
+ cfi: false, // true,
},
},
diff --git a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
index 7864f07..12eaff5 100644
--- a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
+++ b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp
@@ -27,6 +27,8 @@
#include "ih264d.h"
#include "C2SoftAvcDec.h"
+#include <C2PlatformSupport.h>
+
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaDefs.h>
#include <utils/misc.h>
@@ -275,6 +277,8 @@
mMaxVideoSizeHint.mWidth = H264_MAX_FRAME_WIDTH;
mMaxVideoSizeHint.mHeight = H264_MAX_FRAME_HEIGHT;
+ mOutputBlockPools = C2PortBlockPoolsTuning::output::alloc_unique({});
+
auto insertParam = [¶ms = mParams] (C2Param *param) {
params[restoreIndex(param)] = param;
};
@@ -422,6 +426,8 @@
false, "_video_size", &mVideoSize));
mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
false, "_max_video_size_hint", &mMaxVideoSizeHint));
+ mParamDescs.push_back(std::make_shared<C2ParamDescriptor>(
+ false, "_output_block_pools", mOutputBlockPools.get()));
}
C2String C2SoftAvcDecIntf::getName() const {
@@ -443,6 +449,8 @@
uint32_t index = restoreIndex(param);
if (!mParams.count(index)) {
+ // TODO: add support for output-block-pools (this will be done when we move all
+ // config to shared ptr)
continue;
}
@@ -471,6 +479,13 @@
C2Status err = C2_OK;
for (C2Param *param : params) {
uint32_t index = restoreIndex(param);
+ if (param->index() == mOutputBlockPools.get()->index()) {
+ // setting output block pools
+ mOutputBlockPools.reset(
+ (C2PortBlockPoolsTuning::output *)C2Param::Copy(*param).release());
+ continue;
+ }
+
if (mParams.count(index) == 0) {
// We can't create C2SettingResult with no field, so just skipping in this case.
err = C2_BAD_INDEX;
@@ -1211,7 +1226,19 @@
// TODO: format & usage
uint32_t format = HAL_PIXEL_FORMAT_YV12;
C2MemoryUsage usage = { C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite };
- (void) work->worklets.front()->allocators[0]->fetchGraphicBlock(
+ // TODO: lock access to interface
+ C2BlockPool::local_id_t poolId =
+ mIntf->mOutputBlockPools->flexCount() ?
+ mIntf->mOutputBlockPools->m.mValues[0] : C2BlockPool::BASIC_GRAPHIC;
+ if (!mOutputBlockPool || mOutputBlockPool->getLocalId() != poolId) {
+ C2Status err = GetCodec2BlockPool(poolId, shared_from_this(), &mOutputBlockPool);
+ if (err != C2_OK) {
+ // TODO: trip
+ }
+ }
+ ALOGE("using allocator %u", mOutputBlockPool->getAllocatorId());
+
+ (void)mOutputBlockPool->fetchGraphicBlock(
mWidth, mHeight, format, usage, &mAllocatedBlock);
ALOGE("provided (%dx%d) required (%dx%d)", mAllocatedBlock->width(), mAllocatedBlock->height(), mWidth, mHeight);
}
diff --git a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
index cc33083..41ccf39 100644
--- a/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
+++ b/media/libstagefright/codecs/avcdec/C2SoftAvcDec.h
@@ -118,6 +118,7 @@
// TODO: C2StreamMimeConfig mInputStreamMime;
// TODO: C2StreamMimeConfig mOutputStreamMime;
C2StreamFormatConfig::input mInputStreamFormat;
+ std::unique_ptr<C2PortBlockPoolsTuning::output> mOutputBlockPools;
C2StreamFormatConfig::output mOutputStreamFormat;
C2VideoSizeStreamInfo::output mVideoSize;
C2MaxVideoSizeHintPortSetting::input mMaxVideoSizeHint;
@@ -138,6 +139,7 @@
std::vector<std::shared_ptr<C2ParamDescriptor>> mParamDescs;
void updateSupportedValues();
+ friend class C2SoftAvcDec;
};
class C2SoftAvcDec
@@ -191,6 +193,7 @@
const std::shared_ptr<C2SoftAvcDecIntf> mIntf;
const std::shared_ptr<C2ComponentListener> mListener;
+ std::shared_ptr<C2BlockPool> mOutputBlockPool;
std::mutex mQueueLock;
std::condition_variable mQueueCond;
diff --git a/media/libstagefright/codecs/cmds/codec2.cpp b/media/libstagefright/codecs/cmds/codec2.cpp
index 51e1420..c7e1c82 100644
--- a/media/libstagefright/codecs/cmds/codec2.cpp
+++ b/media/libstagefright/codecs/cmds/codec2.cpp
@@ -95,9 +95,7 @@
sp<IProducerListener> mProducerListener;
std::shared_ptr<C2Allocator> mAllocIon;
- std::shared_ptr<C2Allocator> mAllocGralloc;
std::shared_ptr<C2BlockPool> mLinearPool;
- std::shared_ptr<C2BlockPool> mGraphicPool;
std::mutex mQueueLock;
std::condition_variable mQueueCondition;
@@ -145,10 +143,7 @@
std::shared_ptr<C2AllocatorStore> store = GetCodec2PlatformAllocatorStore();
CHECK_EQ(store->getAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mAllocIon), C2_OK);
- CHECK_EQ(store->getAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &mAllocGralloc), C2_OK);
-
mLinearPool = std::make_shared<C2BasicLinearBlockPool>(mAllocIon);
- mGraphicPool = std::make_shared<C2BasicGraphicBlockPool>(mAllocGralloc);
mControl = mComposerClient->createSurface(
String8("A Surface"),
@@ -214,6 +209,10 @@
}
std::shared_ptr<C2Component> component(std::make_shared<C2SoftAvcDec>("avc", 0, mListener));
+ std::unique_ptr<C2PortBlockPoolsTuning::output> pools =
+ C2PortBlockPoolsTuning::output::alloc_unique({ (uint64_t)C2BlockPool::BASIC_GRAPHIC });
+ std::vector<std::unique_ptr<C2SettingResult>> result;
+ (void)component->intf()->config_nb({pools.get()}, &result);
component->start();
for (int i = 0; i < 8; ++i) {
@@ -343,7 +342,6 @@
work->input.buffers.emplace_back(new LinearBuffer(block));
work->worklets.clear();
work->worklets.emplace_back(new C2Worklet);
- work->worklets.front()->allocators.emplace_back(mGraphicPool);
std::list<std::unique_ptr<C2Work>> items;
items.push_back(std::move(work));