1fa7767c5Sopenharmony_ci/*
2fa7767c5Sopenharmony_ci * Copyright (c) 2022-2022 Huawei Device Co., Ltd.
3fa7767c5Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fa7767c5Sopenharmony_ci * you may not use this file except in compliance with the License.
5fa7767c5Sopenharmony_ci * You may obtain a copy of the License at
6fa7767c5Sopenharmony_ci *
7fa7767c5Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fa7767c5Sopenharmony_ci *
9fa7767c5Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fa7767c5Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fa7767c5Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fa7767c5Sopenharmony_ci * See the License for the specific language governing permissions and
13fa7767c5Sopenharmony_ci * limitations under the License.
14fa7767c5Sopenharmony_ci */
15fa7767c5Sopenharmony_ci
16fa7767c5Sopenharmony_ci#if !defined(OHOS_LITE) && defined(VIDEO_SUPPORT)
17fa7767c5Sopenharmony_ci
18fa7767c5Sopenharmony_ci#include "share_memory.h"
19fa7767c5Sopenharmony_ci#include "inner_api/common/log.h"
20fa7767c5Sopenharmony_ci#include "cpp_ext/type_cast_ext.h"
21fa7767c5Sopenharmony_ci#include "securec.h"
22fa7767c5Sopenharmony_ci
23fa7767c5Sopenharmony_cinamespace {
24fa7767c5Sopenharmony_ciconstexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_FOUNDATION, "ShareMemory" };
25fa7767c5Sopenharmony_ci}
26fa7767c5Sopenharmony_ci
27fa7767c5Sopenharmony_cinamespace OHOS {
28fa7767c5Sopenharmony_cinamespace Media {
29fa7767c5Sopenharmony_cinamespace Plugins {
30fa7767c5Sopenharmony_ciShareMemory::ShareMemory(size_t capacity, std::shared_ptr<Allocator> allocator, size_t align)
31fa7767c5Sopenharmony_ci    : Memory(capacity, std::move(allocator), align, MemoryType::SHARED_MEMORY, false)
32fa7767c5Sopenharmony_ci{
33fa7767c5Sopenharmony_ci    size_t allocSize = align ? (capacity + align - 1) : capacity;
34fa7767c5Sopenharmony_ci    if (this->allocator != nullptr && this->allocator->GetMemoryType() == MemoryType::SHARED_MEMORY) {
35fa7767c5Sopenharmony_ci        shareAllocator_ = ReinterpretPointerCast<ShareAllocator>(this->allocator);
36fa7767c5Sopenharmony_ci        fd_ = (uintptr_t)shareAllocator_->Alloc(allocSize);
37fa7767c5Sopenharmony_ci        sharedMem_ = std::make_shared<Ashmem>(fd_, allocSize);
38fa7767c5Sopenharmony_ci        InitShareMemory(shareAllocator_->GetShareMemType());
39fa7767c5Sopenharmony_ci    } else {
40fa7767c5Sopenharmony_ci        MEDIA_LOG_E("create sharedMem_ failed");
41fa7767c5Sopenharmony_ci    }
42fa7767c5Sopenharmony_ci}
43fa7767c5Sopenharmony_ci
44fa7767c5Sopenharmony_ciShareMemory::~ShareMemory()
45fa7767c5Sopenharmony_ci{
46fa7767c5Sopenharmony_ci    if (sharedMem_) {
47fa7767c5Sopenharmony_ci        sharedMem_->UnmapAshmem();
48fa7767c5Sopenharmony_ci        sharedMem_->CloseAshmem();
49fa7767c5Sopenharmony_ci        sharedMem_ = nullptr;
50fa7767c5Sopenharmony_ci    }
51fa7767c5Sopenharmony_ci}
52fa7767c5Sopenharmony_ci
53fa7767c5Sopenharmony_ciuint8_t* ShareMemory::GetRealAddr() const
54fa7767c5Sopenharmony_ci{
55fa7767c5Sopenharmony_ci    auto addr = const_cast<void*>(sharedMem_->ReadFromAshmem(0, 0));
56fa7767c5Sopenharmony_ci    return static_cast<uint8_t*>(addr);
57fa7767c5Sopenharmony_ci}
58fa7767c5Sopenharmony_ci
59fa7767c5Sopenharmony_cisize_t ShareMemory::Write(const uint8_t* in, size_t writeSize, size_t position)
60fa7767c5Sopenharmony_ci{
61fa7767c5Sopenharmony_ci    size_t start = 0;
62fa7767c5Sopenharmony_ci    if (position == MEM_INVALID_POSITION) {
63fa7767c5Sopenharmony_ci        start = size;
64fa7767c5Sopenharmony_ci    } else {
65fa7767c5Sopenharmony_ci        start = std::min(position, capacity);
66fa7767c5Sopenharmony_ci    }
67fa7767c5Sopenharmony_ci    size_t length = std::min(writeSize, capacity - start);
68fa7767c5Sopenharmony_ci    if (!sharedMem_->WriteToAshmem(in, (int32_t)writeSize, (int32_t)start)) {
69fa7767c5Sopenharmony_ci        MEDIA_LOG_E("sharedMem_ WriteToAshmem failed");
70fa7767c5Sopenharmony_ci        return 0;
71fa7767c5Sopenharmony_ci    }
72fa7767c5Sopenharmony_ci    size = start + length;
73fa7767c5Sopenharmony_ci    return length;
74fa7767c5Sopenharmony_ci}
75fa7767c5Sopenharmony_ci
76fa7767c5Sopenharmony_cisize_t ShareMemory::Read(uint8_t* out, size_t readSize, size_t position)
77fa7767c5Sopenharmony_ci{
78fa7767c5Sopenharmony_ci    size_t start = 0;
79fa7767c5Sopenharmony_ci    size_t maxLength = size;
80fa7767c5Sopenharmony_ci    if (position != MEM_INVALID_POSITION) {
81fa7767c5Sopenharmony_ci        start = std::min(position, size);
82fa7767c5Sopenharmony_ci        maxLength = size - start;
83fa7767c5Sopenharmony_ci    }
84fa7767c5Sopenharmony_ci    size_t length = std::min(readSize, maxLength);
85fa7767c5Sopenharmony_ci    if (memcpy_s(out, length, sharedMem_->ReadFromAshmem((int32_t)readSize, (int32_t)start), length) != EOK) {
86fa7767c5Sopenharmony_ci        return 0;
87fa7767c5Sopenharmony_ci    }
88fa7767c5Sopenharmony_ci    return length;
89fa7767c5Sopenharmony_ci}
90fa7767c5Sopenharmony_ci
91fa7767c5Sopenharmony_ciint ShareMemory::GetShareMemoryFd()
92fa7767c5Sopenharmony_ci{
93fa7767c5Sopenharmony_ci    return fd_;
94fa7767c5Sopenharmony_ci}
95fa7767c5Sopenharmony_ci
96fa7767c5Sopenharmony_civoid ShareMemory::InitShareMemory(ShareMemType type)
97fa7767c5Sopenharmony_ci{
98fa7767c5Sopenharmony_ci    switch (type) {
99fa7767c5Sopenharmony_ci        case ShareMemType::READ_ONLY_TYPE :
100fa7767c5Sopenharmony_ci            if (!sharedMem_->MapReadOnlyAshmem()) {
101fa7767c5Sopenharmony_ci                MEDIA_LOG_E("failed to exec MapReadOnlyAshmem");
102fa7767c5Sopenharmony_ci            }
103fa7767c5Sopenharmony_ci            break;
104fa7767c5Sopenharmony_ci        case ShareMemType::READ_WRITE_TYPE :
105fa7767c5Sopenharmony_ci            if (!sharedMem_->MapReadAndWriteAshmem()) {
106fa7767c5Sopenharmony_ci                MEDIA_LOG_E("failed to exec MapReadAndWriteAshmem");
107fa7767c5Sopenharmony_ci            }
108fa7767c5Sopenharmony_ci            break;
109fa7767c5Sopenharmony_ci        default:
110fa7767c5Sopenharmony_ci            MEDIA_LOG_E("set share memory type failed, not find this type: " PUBLIC_LOG_D32,
111fa7767c5Sopenharmony_ci                static_cast<int32_t>(type));
112fa7767c5Sopenharmony_ci            break;
113fa7767c5Sopenharmony_ci    }
114fa7767c5Sopenharmony_ci}
115fa7767c5Sopenharmony_ci} // namespace Plugins
116fa7767c5Sopenharmony_ci} // namespace Media
117fa7767c5Sopenharmony_ci} // namespace OHOS
118fa7767c5Sopenharmony_ci#endif
119fa7767c5Sopenharmony_ci
120