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