Loading media/libstagefright/CCodecBufferChannel.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <numeric> #include <thread> #include <C2AllocatorGralloc.h> #include <C2PlatformSupport.h> #include <android/hardware/cas/native/1.0/IDescrambler.h> Loading Loading @@ -729,8 +730,9 @@ status_t CCodecBufferChannel::renderOutputBuffer( return UNKNOWN_ERROR; } native_handle_t *grallocHandle = UnwrapNativeCodec2GrallocHandle(blocks.front().handle()); sp<GraphicBuffer> graphicBuffer(new GraphicBuffer( blocks.front().handle(), grallocHandle, GraphicBuffer::CLONE_HANDLE, blocks.front().width(), blocks.front().height(), Loading @@ -740,6 +742,7 @@ status_t CCodecBufferChannel::renderOutputBuffer( (uint64_t)GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, // TODO blocks.front().width())); native_handle_delete(grallocHandle); status_t result = (*surface)->attachBuffer(graphicBuffer.get()); if (result != OK) { Loading media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp +139 −10 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <android/hardware/graphics/allocator/2.0/IAllocator.h> #include <android/hardware/graphics/mapper/2.0/IMapper.h> #include <cutils/native_handle.h> #include <hardware/gralloc.h> #include <C2AllocatorGralloc.h> Loading Loading @@ -50,6 +51,111 @@ static c2_status_t maperr2error(Error maperr) { return C2_CORRUPTED; } static bool native_handle_is_invalid(const native_handle_t *const handle) { // perform basic validation of a native handle if (handle == nullptr) { // null handle is considered valid return false; } return ((size_t)handle->version != sizeof(native_handle_t) || handle->numFds < 0 || handle->numInts < 0 || // for sanity assume handles must occupy less memory than INT_MAX bytes handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts); } class C2HandleGralloc : public C2Handle { private: struct ExtraData { uint32_t width; uint32_t height; uint32_t format; uint32_t usage_lo; uint32_t usage_hi; uint32_t magic; }; enum { NUM_INTS = sizeof(ExtraData) / sizeof(int), }; const static uint32_t MAGIC = '\xc2gr\x00'; static const ExtraData* getExtraData(const C2Handle *const handle) { if (handle == nullptr || native_handle_is_invalid(handle) || handle->numInts < NUM_INTS) { return nullptr; } return reinterpret_cast<const ExtraData*>( &handle->data[handle->numFds + handle->numInts - NUM_INTS]); } static ExtraData *getExtraData(C2Handle *const handle) { return const_cast<ExtraData *>(getExtraData(const_cast<const C2Handle *const>(handle))); } public: static bool isValid(const C2Handle *const o) { if (o == nullptr) { // null handle is always valid return true; } const ExtraData *xd = getExtraData(o); // we cannot validate width/height/format/usage without accessing gralloc driver return xd != nullptr && xd->magic == MAGIC; } static C2HandleGralloc* WrapNativeHandle( const native_handle_t *const handle, uint32_t width, uint32_t height, uint32_t format, uint64_t usage) { //CHECK(handle != nullptr); if (native_handle_is_invalid(handle) || handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) { return nullptr; } ExtraData xd = { width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32), MAGIC }; native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS); if (res != nullptr) { memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts)); *getExtraData(res) = xd; } return reinterpret_cast<C2HandleGralloc *>(res); } static native_handle_t* UnwrapNativeHandle(const C2Handle *const handle) { const ExtraData *xd = getExtraData(handle); if (xd == nullptr || xd->magic != MAGIC) { return nullptr; } native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS); if (res != nullptr) { memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts)); } return res; } static const C2HandleGralloc* Import( const C2Handle *const handle, uint32_t *width, uint32_t *height, uint32_t *format, uint64_t *usage) { const ExtraData *xd = getExtraData(handle); if (xd == nullptr) { return nullptr; } *width = xd->width; *height = xd->height; *format = xd->format; *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32); return reinterpret_cast<const C2HandleGralloc *>(handle); } }; native_handle_t* UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) { return C2HandleGralloc::UnwrapNativeHandle(handle); } class C2AllocationGralloc : public C2GraphicAllocation { public: virtual ~C2AllocationGralloc() override; Loading @@ -59,7 +165,7 @@ public: C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override; virtual c2_status_t unmap(C2Fence *fenceFd /* nullable */) override; virtual bool isValid() const override { return true; } virtual const C2Handle *handle() const override { return mHandle; } virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; } virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override; // internal methods Loading @@ -67,26 +173,31 @@ public: C2AllocationGralloc( const IMapper::BufferDescriptorInfo &info, const sp<IMapper> &mapper, hidl_handle &handle); hidl_handle &hidlHandle, const C2HandleGralloc *const handle); int dup() const; c2_status_t status() const; private: const IMapper::BufferDescriptorInfo mInfo; const sp<IMapper> mMapper; const hidl_handle mHandle; const hidl_handle mHidlHandle; const C2HandleGralloc *mHandle; buffer_handle_t mBuffer; const C2HandleGralloc *mLockedHandle; bool mLocked; }; C2AllocationGralloc::C2AllocationGralloc( const IMapper::BufferDescriptorInfo &info, const sp<IMapper> &mapper, hidl_handle &handle) hidl_handle &hidlHandle, const C2HandleGralloc *const handle) : C2GraphicAllocation(info.width, info.height), mInfo(info), mMapper(mapper), mHandle(std::move(handle)), mHidlHandle(std::move(hidlHandle)), mHandle(handle), mBuffer(nullptr), mLocked(false) {} Loading Loading @@ -117,7 +228,7 @@ c2_status_t C2AllocationGralloc::map( c2_status_t err = C2_OK; if (!mBuffer) { mMapper->importBuffer( mHandle, [&err, this](const auto &maperr, const auto &buffer) { mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) { err = maperr2error(maperr); if (err == C2_OK) { mBuffer = static_cast<buffer_handle_t>(buffer); Loading @@ -126,6 +237,11 @@ c2_status_t C2AllocationGralloc::map( if (err != C2_OK) { return err; } if (mBuffer == nullptr) { return C2_CORRUPTED; } mLockedHandle = C2HandleGralloc::WrapNativeHandle( mBuffer, mInfo.width, mInfo.height, (uint32_t)mInfo.format, mInfo.usage); } if (mInfo.format == PixelFormat::YCBCR_420_888 || mInfo.format == PixelFormat::YV12) { Loading Loading @@ -321,17 +437,30 @@ c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation( return err; } allocation->reset(new C2AllocationGralloc(info, mMapper, buffer)); allocation->reset(new C2AllocationGralloc( info, mMapper, buffer, C2HandleGralloc::WrapNativeHandle( buffer.getNativeHandle(), info.width, info.height, (uint32_t)info.format, info.usage))); return C2_OK; } c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation( const C2Handle *handle, std::shared_ptr<C2GraphicAllocation> *allocation) { (void) handle; IMapper::BufferDescriptorInfo info; info.layerCount = 1u; const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import( handle, &info.width, &info.height, (uint32_t *)&info.format, (uint64_t *)&info.usage); if (grallocHandle == nullptr) { return C2_BAD_VALUE; } hidl_handle hidlHandle = C2HandleGralloc::UnwrapNativeHandle(grallocHandle); // TODO: need to figure out BufferDescriptorInfo from the handle. allocation->reset(); allocation->reset(new C2AllocationGralloc(info, mMapper, hidlHandle, grallocHandle)); return C2_OMITTED; } Loading media/libstagefright/codec2/vndk/include/C2AllocatorGralloc.h +10 −4 Original line number Diff line number Diff line Loading @@ -24,12 +24,18 @@ namespace android { /** * Unwrap the native handle from a Codec2 handle allocated by C2AllocatorGralloc. * * @param handle a handle allocated by C2AllocatorGralloc. This includes handles returned for a * graphic block allocation handle returned. * * @return a new NON-OWNING native handle that must be deleted using native_handle_delete. */ native_handle_t*UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle); class C2AllocatorGralloc : public C2Allocator { public: // (usage, capacity) => (align, heapMask, flags) typedef std::function<int (C2MemoryUsage, size_t, /* => */ size_t*, unsigned*, unsigned*)> usage_mapper_fn; virtual id_t getId() const override; virtual C2String getName() const override; Loading media/libstagefright/codecs/cmds/codec2.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ #include <gui/SurfaceComposerClient.h> #include <util/C2ParamUtils.h> #include <C2AllocatorGralloc.h> #include <C2Buffer.h> #include <C2BufferPriv.h> #include <C2Component.h> Loading Loading @@ -250,8 +251,9 @@ void SimplePlayer::play(const sp<IMediaSource> &source) { const std::shared_ptr<C2Buffer> &output = work->worklets.front()->output.buffers[0]; if (output) { const C2ConstGraphicBlock &block = output->data().graphicBlocks().front(); native_handle_t *grallocHandle = UnwrapNativeCodec2GrallocHandle(block.handle()); sp<GraphicBuffer> buffer(new GraphicBuffer( block.handle(), grallocHandle, GraphicBuffer::CLONE_HANDLE, block.width(), block.height(), Loading @@ -259,6 +261,7 @@ void SimplePlayer::play(const sp<IMediaSource> &source) { 1, (uint64_t)GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, block.width())); native_handle_delete(grallocHandle); status_t err = igbp->attachBuffer(&slot, buffer); Loading Loading
media/libstagefright/CCodecBufferChannel.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <numeric> #include <thread> #include <C2AllocatorGralloc.h> #include <C2PlatformSupport.h> #include <android/hardware/cas/native/1.0/IDescrambler.h> Loading Loading @@ -729,8 +730,9 @@ status_t CCodecBufferChannel::renderOutputBuffer( return UNKNOWN_ERROR; } native_handle_t *grallocHandle = UnwrapNativeCodec2GrallocHandle(blocks.front().handle()); sp<GraphicBuffer> graphicBuffer(new GraphicBuffer( blocks.front().handle(), grallocHandle, GraphicBuffer::CLONE_HANDLE, blocks.front().width(), blocks.front().height(), Loading @@ -740,6 +742,7 @@ status_t CCodecBufferChannel::renderOutputBuffer( (uint64_t)GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, // TODO blocks.front().width())); native_handle_delete(grallocHandle); status_t result = (*surface)->attachBuffer(graphicBuffer.get()); if (result != OK) { Loading
media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp +139 −10 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <android/hardware/graphics/allocator/2.0/IAllocator.h> #include <android/hardware/graphics/mapper/2.0/IMapper.h> #include <cutils/native_handle.h> #include <hardware/gralloc.h> #include <C2AllocatorGralloc.h> Loading Loading @@ -50,6 +51,111 @@ static c2_status_t maperr2error(Error maperr) { return C2_CORRUPTED; } static bool native_handle_is_invalid(const native_handle_t *const handle) { // perform basic validation of a native handle if (handle == nullptr) { // null handle is considered valid return false; } return ((size_t)handle->version != sizeof(native_handle_t) || handle->numFds < 0 || handle->numInts < 0 || // for sanity assume handles must occupy less memory than INT_MAX bytes handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts); } class C2HandleGralloc : public C2Handle { private: struct ExtraData { uint32_t width; uint32_t height; uint32_t format; uint32_t usage_lo; uint32_t usage_hi; uint32_t magic; }; enum { NUM_INTS = sizeof(ExtraData) / sizeof(int), }; const static uint32_t MAGIC = '\xc2gr\x00'; static const ExtraData* getExtraData(const C2Handle *const handle) { if (handle == nullptr || native_handle_is_invalid(handle) || handle->numInts < NUM_INTS) { return nullptr; } return reinterpret_cast<const ExtraData*>( &handle->data[handle->numFds + handle->numInts - NUM_INTS]); } static ExtraData *getExtraData(C2Handle *const handle) { return const_cast<ExtraData *>(getExtraData(const_cast<const C2Handle *const>(handle))); } public: static bool isValid(const C2Handle *const o) { if (o == nullptr) { // null handle is always valid return true; } const ExtraData *xd = getExtraData(o); // we cannot validate width/height/format/usage without accessing gralloc driver return xd != nullptr && xd->magic == MAGIC; } static C2HandleGralloc* WrapNativeHandle( const native_handle_t *const handle, uint32_t width, uint32_t height, uint32_t format, uint64_t usage) { //CHECK(handle != nullptr); if (native_handle_is_invalid(handle) || handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) { return nullptr; } ExtraData xd = { width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32), MAGIC }; native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS); if (res != nullptr) { memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts)); *getExtraData(res) = xd; } return reinterpret_cast<C2HandleGralloc *>(res); } static native_handle_t* UnwrapNativeHandle(const C2Handle *const handle) { const ExtraData *xd = getExtraData(handle); if (xd == nullptr || xd->magic != MAGIC) { return nullptr; } native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS); if (res != nullptr) { memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts)); } return res; } static const C2HandleGralloc* Import( const C2Handle *const handle, uint32_t *width, uint32_t *height, uint32_t *format, uint64_t *usage) { const ExtraData *xd = getExtraData(handle); if (xd == nullptr) { return nullptr; } *width = xd->width; *height = xd->height; *format = xd->format; *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32); return reinterpret_cast<const C2HandleGralloc *>(handle); } }; native_handle_t* UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) { return C2HandleGralloc::UnwrapNativeHandle(handle); } class C2AllocationGralloc : public C2GraphicAllocation { public: virtual ~C2AllocationGralloc() override; Loading @@ -59,7 +165,7 @@ public: C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override; virtual c2_status_t unmap(C2Fence *fenceFd /* nullable */) override; virtual bool isValid() const override { return true; } virtual const C2Handle *handle() const override { return mHandle; } virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; } virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override; // internal methods Loading @@ -67,26 +173,31 @@ public: C2AllocationGralloc( const IMapper::BufferDescriptorInfo &info, const sp<IMapper> &mapper, hidl_handle &handle); hidl_handle &hidlHandle, const C2HandleGralloc *const handle); int dup() const; c2_status_t status() const; private: const IMapper::BufferDescriptorInfo mInfo; const sp<IMapper> mMapper; const hidl_handle mHandle; const hidl_handle mHidlHandle; const C2HandleGralloc *mHandle; buffer_handle_t mBuffer; const C2HandleGralloc *mLockedHandle; bool mLocked; }; C2AllocationGralloc::C2AllocationGralloc( const IMapper::BufferDescriptorInfo &info, const sp<IMapper> &mapper, hidl_handle &handle) hidl_handle &hidlHandle, const C2HandleGralloc *const handle) : C2GraphicAllocation(info.width, info.height), mInfo(info), mMapper(mapper), mHandle(std::move(handle)), mHidlHandle(std::move(hidlHandle)), mHandle(handle), mBuffer(nullptr), mLocked(false) {} Loading Loading @@ -117,7 +228,7 @@ c2_status_t C2AllocationGralloc::map( c2_status_t err = C2_OK; if (!mBuffer) { mMapper->importBuffer( mHandle, [&err, this](const auto &maperr, const auto &buffer) { mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) { err = maperr2error(maperr); if (err == C2_OK) { mBuffer = static_cast<buffer_handle_t>(buffer); Loading @@ -126,6 +237,11 @@ c2_status_t C2AllocationGralloc::map( if (err != C2_OK) { return err; } if (mBuffer == nullptr) { return C2_CORRUPTED; } mLockedHandle = C2HandleGralloc::WrapNativeHandle( mBuffer, mInfo.width, mInfo.height, (uint32_t)mInfo.format, mInfo.usage); } if (mInfo.format == PixelFormat::YCBCR_420_888 || mInfo.format == PixelFormat::YV12) { Loading Loading @@ -321,17 +437,30 @@ c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation( return err; } allocation->reset(new C2AllocationGralloc(info, mMapper, buffer)); allocation->reset(new C2AllocationGralloc( info, mMapper, buffer, C2HandleGralloc::WrapNativeHandle( buffer.getNativeHandle(), info.width, info.height, (uint32_t)info.format, info.usage))); return C2_OK; } c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation( const C2Handle *handle, std::shared_ptr<C2GraphicAllocation> *allocation) { (void) handle; IMapper::BufferDescriptorInfo info; info.layerCount = 1u; const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import( handle, &info.width, &info.height, (uint32_t *)&info.format, (uint64_t *)&info.usage); if (grallocHandle == nullptr) { return C2_BAD_VALUE; } hidl_handle hidlHandle = C2HandleGralloc::UnwrapNativeHandle(grallocHandle); // TODO: need to figure out BufferDescriptorInfo from the handle. allocation->reset(); allocation->reset(new C2AllocationGralloc(info, mMapper, hidlHandle, grallocHandle)); return C2_OMITTED; } Loading
media/libstagefright/codec2/vndk/include/C2AllocatorGralloc.h +10 −4 Original line number Diff line number Diff line Loading @@ -24,12 +24,18 @@ namespace android { /** * Unwrap the native handle from a Codec2 handle allocated by C2AllocatorGralloc. * * @param handle a handle allocated by C2AllocatorGralloc. This includes handles returned for a * graphic block allocation handle returned. * * @return a new NON-OWNING native handle that must be deleted using native_handle_delete. */ native_handle_t*UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle); class C2AllocatorGralloc : public C2Allocator { public: // (usage, capacity) => (align, heapMask, flags) typedef std::function<int (C2MemoryUsage, size_t, /* => */ size_t*, unsigned*, unsigned*)> usage_mapper_fn; virtual id_t getId() const override; virtual C2String getName() const override; Loading
media/libstagefright/codecs/cmds/codec2.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ #include <gui/SurfaceComposerClient.h> #include <util/C2ParamUtils.h> #include <C2AllocatorGralloc.h> #include <C2Buffer.h> #include <C2BufferPriv.h> #include <C2Component.h> Loading Loading @@ -250,8 +251,9 @@ void SimplePlayer::play(const sp<IMediaSource> &source) { const std::shared_ptr<C2Buffer> &output = work->worklets.front()->output.buffers[0]; if (output) { const C2ConstGraphicBlock &block = output->data().graphicBlocks().front(); native_handle_t *grallocHandle = UnwrapNativeCodec2GrallocHandle(block.handle()); sp<GraphicBuffer> buffer(new GraphicBuffer( block.handle(), grallocHandle, GraphicBuffer::CLONE_HANDLE, block.width(), block.height(), Loading @@ -259,6 +261,7 @@ void SimplePlayer::play(const sp<IMediaSource> &source) { 1, (uint64_t)GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, block.width())); native_handle_delete(grallocHandle); status_t err = igbp->attachBuffer(&slot, buffer); Loading