/* * Copyright (c) 2022-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined(OHOS_LITE) && defined(VIDEO_SUPPORT) #include "share_memory.h" #include "inner_api/common/log.h" #include "cpp_ext/type_cast_ext.h" #include "securec.h" namespace { constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_FOUNDATION, "ShareMemory" }; } namespace OHOS { namespace Media { namespace Plugins { ShareMemory::ShareMemory(size_t capacity, std::shared_ptr allocator, size_t align) : Memory(capacity, std::move(allocator), align, MemoryType::SHARED_MEMORY, false) { size_t allocSize = align ? (capacity + align - 1) : capacity; if (this->allocator != nullptr && this->allocator->GetMemoryType() == MemoryType::SHARED_MEMORY) { shareAllocator_ = ReinterpretPointerCast(this->allocator); fd_ = (uintptr_t)shareAllocator_->Alloc(allocSize); sharedMem_ = std::make_shared(fd_, allocSize); InitShareMemory(shareAllocator_->GetShareMemType()); } else { MEDIA_LOG_E("create sharedMem_ failed"); } } ShareMemory::~ShareMemory() { if (sharedMem_) { sharedMem_->UnmapAshmem(); sharedMem_->CloseAshmem(); sharedMem_ = nullptr; } } uint8_t* ShareMemory::GetRealAddr() const { auto addr = const_cast(sharedMem_->ReadFromAshmem(0, 0)); return static_cast(addr); } size_t ShareMemory::Write(const uint8_t* in, size_t writeSize, size_t position) { size_t start = 0; if (position == MEM_INVALID_POSITION) { start = size; } else { start = std::min(position, capacity); } size_t length = std::min(writeSize, capacity - start); if (!sharedMem_->WriteToAshmem(in, (int32_t)writeSize, (int32_t)start)) { MEDIA_LOG_E("sharedMem_ WriteToAshmem failed"); return 0; } size = start + length; return length; } size_t ShareMemory::Read(uint8_t* out, size_t readSize, size_t position) { size_t start = 0; size_t maxLength = size; if (position != MEM_INVALID_POSITION) { start = std::min(position, size); maxLength = size - start; } size_t length = std::min(readSize, maxLength); if (memcpy_s(out, length, sharedMem_->ReadFromAshmem((int32_t)readSize, (int32_t)start), length) != EOK) { return 0; } return length; } int ShareMemory::GetShareMemoryFd() { return fd_; } void ShareMemory::InitShareMemory(ShareMemType type) { switch (type) { case ShareMemType::READ_ONLY_TYPE : if (!sharedMem_->MapReadOnlyAshmem()) { MEDIA_LOG_E("failed to exec MapReadOnlyAshmem"); } break; case ShareMemType::READ_WRITE_TYPE : if (!sharedMem_->MapReadAndWriteAshmem()) { MEDIA_LOG_E("failed to exec MapReadAndWriteAshmem"); } break; default: MEDIA_LOG_E("set share memory type failed, not find this type: " PUBLIC_LOG_D32, static_cast(type)); break; } } } // namespace Plugins } // namespace Media } // namespace OHOS #endif