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 "plugin/common/share_memory.h"
19fa7767c5Sopenharmony_ci#include "foundation/log.h"
20fa7767c5Sopenharmony_ci
21fa7767c5Sopenharmony_cinamespace OHOS {
22fa7767c5Sopenharmony_cinamespace Media {
23fa7767c5Sopenharmony_cinamespace Plugin {
24fa7767c5Sopenharmony_ciShareMemory::ShareMemory(size_t capacity, std::shared_ptr<Allocator> allocator, size_t align)
25fa7767c5Sopenharmony_ci    : Memory(capacity, std::move(allocator), align, MemoryType::SHARE_MEMORY, false)
26fa7767c5Sopenharmony_ci{
27fa7767c5Sopenharmony_ci    size_t allocSize = align ? (capacity + align - 1) : capacity;
28fa7767c5Sopenharmony_ci    if (this->allocator != nullptr && this->allocator->GetMemoryType() == MemoryType::SHARE_MEMORY) {
29fa7767c5Sopenharmony_ci        shareAllocator_ = ReinterpretPointerCast<ShareAllocator>(this->allocator);
30fa7767c5Sopenharmony_ci        fd_ = (uintptr_t)shareAllocator_->Alloc(allocSize);
31fa7767c5Sopenharmony_ci        sharedMem_ = std::make_shared<Ashmem>(fd_, allocSize);
32fa7767c5Sopenharmony_ci        InitShareMemory(shareAllocator_->GetShareMemType());
33fa7767c5Sopenharmony_ci    } else {
34fa7767c5Sopenharmony_ci        MEDIA_LOG_E("create sharedMem_ failed");
35fa7767c5Sopenharmony_ci    }
36fa7767c5Sopenharmony_ci}
37fa7767c5Sopenharmony_ci
38fa7767c5Sopenharmony_ciShareMemory::~ShareMemory()
39fa7767c5Sopenharmony_ci{
40fa7767c5Sopenharmony_ci    if (sharedMem_) {
41fa7767c5Sopenharmony_ci        sharedMem_->UnmapAshmem();
42fa7767c5Sopenharmony_ci        sharedMem_->CloseAshmem();
43fa7767c5Sopenharmony_ci        sharedMem_ = nullptr;
44fa7767c5Sopenharmony_ci    }
45fa7767c5Sopenharmony_ci}
46fa7767c5Sopenharmony_ci
47fa7767c5Sopenharmony_ciuint8_t* ShareMemory::GetRealAddr() const
48fa7767c5Sopenharmony_ci{
49fa7767c5Sopenharmony_ci    auto addr = const_cast<void*>(sharedMem_->ReadFromAshmem(0, 0));
50fa7767c5Sopenharmony_ci    return static_cast<uint8_t*>(addr);
51fa7767c5Sopenharmony_ci}
52fa7767c5Sopenharmony_ci
53fa7767c5Sopenharmony_cisize_t ShareMemory::Write(const uint8_t* in, size_t writeSize, size_t position)
54fa7767c5Sopenharmony_ci{
55fa7767c5Sopenharmony_ci    size_t start = 0;
56fa7767c5Sopenharmony_ci    if (position == INVALID_POSITION) {
57fa7767c5Sopenharmony_ci        start = size;
58fa7767c5Sopenharmony_ci    } else {
59fa7767c5Sopenharmony_ci        start = std::min(position, capacity);
60fa7767c5Sopenharmony_ci    }
61fa7767c5Sopenharmony_ci    size_t length = std::min(writeSize, capacity - start);
62fa7767c5Sopenharmony_ci    if (!sharedMem_->WriteToAshmem(in, (int32_t)writeSize, (int32_t)start)) {
63fa7767c5Sopenharmony_ci        MEDIA_LOG_E("sharedMem_ WriteToAshmem failed");
64fa7767c5Sopenharmony_ci        return 0;
65fa7767c5Sopenharmony_ci    }
66fa7767c5Sopenharmony_ci    size = start + length;
67fa7767c5Sopenharmony_ci    return length;
68fa7767c5Sopenharmony_ci}
69fa7767c5Sopenharmony_ci
70fa7767c5Sopenharmony_cisize_t ShareMemory::Read(uint8_t* out, size_t readSize, size_t position)
71fa7767c5Sopenharmony_ci{
72fa7767c5Sopenharmony_ci    size_t start = 0;
73fa7767c5Sopenharmony_ci    size_t maxLength = size;
74fa7767c5Sopenharmony_ci    if (position != INVALID_POSITION) {
75fa7767c5Sopenharmony_ci        start = std::min(position, size);
76fa7767c5Sopenharmony_ci        maxLength = size - start;
77fa7767c5Sopenharmony_ci    }
78fa7767c5Sopenharmony_ci    size_t length = std::min(readSize, maxLength);
79fa7767c5Sopenharmony_ci    if (memcpy_s(out, length, sharedMem_->ReadFromAshmem((int32_t)readSize, (int32_t)start), length) != EOK) {
80fa7767c5Sopenharmony_ci        return 0;
81fa7767c5Sopenharmony_ci    }
82fa7767c5Sopenharmony_ci    return length;
83fa7767c5Sopenharmony_ci}
84fa7767c5Sopenharmony_ci
85fa7767c5Sopenharmony_ciint ShareMemory::GetShareMemoryFd()
86fa7767c5Sopenharmony_ci{
87fa7767c5Sopenharmony_ci    return fd_;
88fa7767c5Sopenharmony_ci}
89fa7767c5Sopenharmony_ci
90fa7767c5Sopenharmony_civoid ShareMemory::InitShareMemory(ShareMemType type)
91fa7767c5Sopenharmony_ci{
92fa7767c5Sopenharmony_ci    switch (type) {
93fa7767c5Sopenharmony_ci        case ShareMemType::READ_ONLY_TYPE :
94fa7767c5Sopenharmony_ci            if (!sharedMem_->MapReadOnlyAshmem()) {
95fa7767c5Sopenharmony_ci                MEDIA_LOG_E("failed to exec MapReadOnlyAshmem");
96fa7767c5Sopenharmony_ci            }
97fa7767c5Sopenharmony_ci            break;
98fa7767c5Sopenharmony_ci        case ShareMemType::READ_WRITE_TYPE :
99fa7767c5Sopenharmony_ci            if (!sharedMem_->MapReadAndWriteAshmem()) {
100fa7767c5Sopenharmony_ci                MEDIA_LOG_E("failed to exec MapReadAndWriteAshmem");
101fa7767c5Sopenharmony_ci            }
102fa7767c5Sopenharmony_ci            break;
103fa7767c5Sopenharmony_ci        default:
104fa7767c5Sopenharmony_ci            MEDIA_LOG_E("set share memory type failed, not find this type: " PUBLIC_LOG_D32,
105fa7767c5Sopenharmony_ci                static_cast<int32_t>(type));
106fa7767c5Sopenharmony_ci            break;
107fa7767c5Sopenharmony_ci    }
108fa7767c5Sopenharmony_ci}
109fa7767c5Sopenharmony_ci} // namespace Plugin
110fa7767c5Sopenharmony_ci} // namespace Media
111fa7767c5Sopenharmony_ci} // namespace OHOS
112fa7767c5Sopenharmony_ci#endif
113fa7767c5Sopenharmony_ci
114