• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
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 #include "gst_shmemory_wrap_allocator.h"
17 #include "securec.h"
18 #include "media_log.h"
19 #include "scope_guard.h"
20 using namespace OHOS;
21 
22 #define gst_shmemory_wrap_allocator_parent_class parent_class
23 G_DEFINE_TYPE(GstShMemoryWrapAllocator, gst_shmemory_wrap_allocator, GST_TYPE_ALLOCATOR);
24 
gst_shmemory_wrap_allocator_new(void)25 GstShMemoryWrapAllocator *gst_shmemory_wrap_allocator_new(void)
26 {
27     GstShMemoryWrapAllocator *alloc = GST_SHMEMORY_WRAP_ALLOCATOR_CAST(g_object_new(
28         GST_TYPE_SHMEMORY_WRAP_ALLOCATOR, "name", "ShmemoryWrapAllocator", nullptr));
29     (void)gst_object_ref_sink(alloc);
30 
31     return alloc;
32 }
33 
gst_shmemory_wrap(GstAllocator * allocator,std::shared_ptr<OHOS::Media::AVSharedMemory> shmem,int32_t offset,int32_t length,int32_t sub,FreeMemory free_memory)34 GstMemory *gst_shmemory_wrap(GstAllocator *allocator, std::shared_ptr<OHOS::Media::AVSharedMemory> shmem,
35     int32_t offset, int32_t length, int32_t sub, FreeMemory free_memory)
36 {
37     g_return_val_if_fail(allocator != nullptr, nullptr);
38     g_return_val_if_fail(shmem != nullptr, nullptr);
39 
40     GstShMemoryWrapMemory *memory =
41         reinterpret_cast<GstShMemoryWrapMemory *>(g_slice_alloc0(sizeof(GstShMemoryWrapMemory)));
42     g_return_val_if_fail(memory != nullptr, nullptr);
43 
44     gst_memory_init(GST_MEMORY_CAST(memory), GST_MEMORY_FLAG_NO_SHARE, allocator,
45         nullptr, length, 0, 0, length);
46 
47     memory->shmemory = shmem;
48     memory->offset = offset;
49     memory->length = length;
50     memory->sub = sub;
51     memory->free_memory = free_memory;
52     GST_DEBUG("wrap memory for size: %" PRIu64 ", addr: 0x%06" PRIXPTR "",
53         static_cast<uint64_t>(length), FAKE_POINTER(
54             std::static_pointer_cast<OHOS::Media::AVDataSrcMemory>(memory->shmemory)->GetInnerBase() + offset));
55 
56     return GST_MEMORY_CAST(memory);
57 }
58 
gst_shmemory_wrap_allocator_alloc(GstAllocator * allocator,gsize size,GstAllocationParams * params)59 static GstMemory *gst_shmemory_wrap_allocator_alloc(GstAllocator *allocator, gsize size, GstAllocationParams *params)
60 {
61     (void)allocator;
62     (void)size;
63     (void)params;
64     return nullptr;
65 }
66 
gst_shmemory_wrap_allocator_free(GstAllocator * allocator,GstMemory * memory)67 static void gst_shmemory_wrap_allocator_free(GstAllocator *allocator, GstMemory *memory)
68 {
69     g_return_if_fail(memory != nullptr && allocator != nullptr);
70     g_return_if_fail(gst_is_shmemory_wrap_memory(memory));
71 
72     GstShMemoryWrapMemory *shWrapMem = reinterpret_cast<GstShMemoryWrapMemory *>(memory);
73     GST_DEBUG("free memory for size: %" G_GSIZE_FORMAT ", shWrapMem->offset %d, addr: 0x%06" PRIXPTR "",
74     memory->maxsize, shWrapMem->offset, FAKE_POINTER(
75         std::static_pointer_cast<OHOS::Media::AVDataSrcMemory>(shWrapMem->shmemory)->GetInnerBase() +
76         shWrapMem->offset));
77 
78     shWrapMem->shmemory = nullptr;
79     if (shWrapMem->free_memory) {
80         shWrapMem->free_memory(shWrapMem->offset, shWrapMem->length, shWrapMem->sub);
81     }
82     g_slice_free(GstShMemoryWrapMemory, shWrapMem);
83 }
84 
gst_shmemory_wrap_allocator_mem_map(GstMemory * mem,gsize maxsize,GstMapFlags flags)85 static gpointer gst_shmemory_wrap_allocator_mem_map(GstMemory *mem, gsize maxsize, GstMapFlags flags)
86 {
87     (void)maxsize;
88     (void)flags;
89     g_return_val_if_fail(mem != nullptr, nullptr);
90     g_return_val_if_fail(gst_is_shmemory_wrap_memory(mem), nullptr);
91 
92     GstShMemoryWrapMemory *shWrapMem = reinterpret_cast<GstShMemoryWrapMemory *>(mem);
93     g_return_val_if_fail(shWrapMem->shmemory != nullptr, nullptr);
94 
95     GST_INFO("mem_map, maxsize: %" G_GSIZE_FORMAT ", size: %" G_GSIZE_FORMAT", addr: 0x%06" PRIXPTR "",
96         mem->maxsize, mem->size, FAKE_POINTER(
97             std::static_pointer_cast<OHOS::Media::AVDataSrcMemory>(shWrapMem->shmemory)->GetInnerBase() +
98             shWrapMem->offset));
99 
100     return std::static_pointer_cast<OHOS::Media::AVDataSrcMemory>(shWrapMem->shmemory)->GetInnerBase() +
101         shWrapMem->offset;
102 }
103 
gst_shmemory_wrap_allocator_mem_unmap(GstMemory * mem)104 static void gst_shmemory_wrap_allocator_mem_unmap(GstMemory *mem)
105 {
106     (void)mem;
107 }
108 
gst_shmemory_wrap_allocator_mem_share(GstMemory * mem,gssize offset,gssize size)109 static GstMemory *gst_shmemory_wrap_allocator_mem_share(GstMemory *mem, gssize offset, gssize size)
110 {
111     g_return_val_if_fail(mem != nullptr &&
112         reinterpret_cast<GstShMemoryWrapMemory *>(mem)->shmemory != nullptr, nullptr);
113     g_return_val_if_fail(offset >= 0 && static_cast<gsize>(offset) < mem->size, nullptr);
114     GST_DEBUG("begin gst_shmemory_wrap_allocator_mem_share, offset is %" G_GSSIZE_FORMAT ","
115         "size is %" G_GSSIZE_FORMAT "", offset, size);
116     GstShMemoryWrapMemory *sub = nullptr;
117     GstMemory *parent = nullptr;
118 
119     /* find the real parent */
120     if ((parent = mem->parent) == NULL) {
121         parent = reinterpret_cast<GstMemory *>(mem);
122     }
123     if (size == -1) {
124         size = mem->size - offset;
125     }
126 
127     sub = g_slice_new0(GstShMemoryWrapMemory);
128     g_return_val_if_fail(sub != nullptr, nullptr);
129     /* the shared memory is always readonly */
130     GST_DEBUG("mem->maxsize is %" G_GSIZE_FORMAT "", mem->maxsize);
131     gst_memory_init(
132         GST_MEMORY_CAST(sub),
133         (GstMemoryFlags)(GST_MINI_OBJECT_FLAGS(parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY),
134         mem->allocator,
135         GST_MEMORY_CAST(parent),
136         mem->maxsize,
137         mem->align,
138         mem->offset,
139         size);
140 
141     sub->shmemory = reinterpret_cast<GstShMemoryWrapMemory *>(mem)->shmemory;
142     sub->offset = reinterpret_cast<GstShMemoryWrapMemory *>(mem)->offset + offset;
143     sub->length = size;
144     GST_DEBUG("gst_shmemory_wrap_allocator_mem_share, addr: 0x%06" PRIXPTR "", FAKE_POINTER(
145         std::static_pointer_cast<OHOS::Media::AVDataSrcMemory>(sub->shmemory)->GetInnerBase() + sub->offset));
146     return GST_MEMORY_CAST(sub);
147 }
148 
gst_shmemory_wrap_allocator_mem_copy(GstShMemoryWrapMemory * mem,gssize offset,gssize size)149 static GstMemory *gst_shmemory_wrap_allocator_mem_copy(GstShMemoryWrapMemory *mem, gssize offset, gssize size)
150 {
151     g_return_val_if_fail(mem != nullptr && mem->shmemory != nullptr, nullptr);
152     g_return_val_if_fail(offset >= 0 && offset < mem->length, nullptr);
153     GST_DEBUG("in gst_shmemory_wrap_allocator_mem_copy, offset is %" G_GSSIZE_FORMAT ","
154         "size is %" G_GSSIZE_FORMAT "", offset, size);
155 
156     gssize realOffset = static_cast<gssize>(mem->offset) + offset;
157     g_return_val_if_fail(realOffset >= 0, nullptr);
158     size = size == -1 ? static_cast<gssize>(mem->length) - offset : size;
159     g_return_val_if_fail(size > 0, nullptr);
160 
161     GstMemory *copy = gst_allocator_alloc(nullptr, static_cast<gsize>(size), nullptr);
162     g_return_val_if_fail(copy != nullptr, nullptr);
163 
164     GstMapInfo info = GST_MAP_INFO_INIT;
165     ON_SCOPE_EXIT(0) { gst_memory_unref(copy); };
166     g_return_val_if_fail(gst_memory_map(copy, &info, GST_MAP_READ), nullptr);
167     ON_SCOPE_EXIT(1) { gst_memory_unmap(copy, &info); };
168 
169     uint8_t *src = std::static_pointer_cast<OHOS::Media::AVDataSrcMemory>(mem->shmemory)->GetInnerBase() + realOffset;
170     errno_t rc = memcpy_s(info.data, info.size, src, static_cast<size_t>(size));
171     g_return_val_if_fail(rc == EOK, nullptr);
172     GST_DEBUG("realOffset is %" G_GSSIZE_FORMAT ", size is %" G_GSSIZE_FORMAT ", src addr: 0x%06" PRIXPTR "",
173         realOffset, size, FAKE_POINTER(
174             std::static_pointer_cast<OHOS::Media::AVDataSrcMemory>(mem->shmemory)->GetInnerBase() + realOffset));
175 
176     CANCEL_SCOPE_EXIT_GUARD(0);
177     return copy;
178 }
179 
gst_shmemory_wrap_allocator_init(GstShMemoryWrapAllocator * allocator)180 static void gst_shmemory_wrap_allocator_init(GstShMemoryWrapAllocator *allocator)
181 {
182     GstAllocator *bAllocator = GST_ALLOCATOR_CAST(allocator);
183     g_return_if_fail(bAllocator != nullptr);
184 
185     GST_DEBUG_OBJECT(allocator, "init allocator 0x%06" PRIXPTR "", FAKE_POINTER(allocator));
186 
187     bAllocator->mem_type = GST_SHMEMORY_WRAP_MEMORY_TYPE;
188     bAllocator->mem_map = (GstMemoryMapFunction)gst_shmemory_wrap_allocator_mem_map;
189     bAllocator->mem_unmap = (GstMemoryUnmapFunction)gst_shmemory_wrap_allocator_mem_unmap;
190     bAllocator->mem_share = (GstMemoryShareFunction)gst_shmemory_wrap_allocator_mem_share;
191     bAllocator->mem_copy = (GstMemoryCopyFunction)gst_shmemory_wrap_allocator_mem_copy;
192 }
193 
gst_shmemory_wrap_allocator_finalize(GObject * obj)194 static void gst_shmemory_wrap_allocator_finalize(GObject *obj)
195 {
196     GstShMemoryWrapAllocator *allocator = GST_SHMEMORY_WRAP_ALLOCATOR_CAST(obj);
197     g_return_if_fail(allocator != nullptr);
198 
199     GST_DEBUG_OBJECT(allocator, "finalize allocator 0x%06" PRIXPTR "", FAKE_POINTER(allocator));
200     G_OBJECT_CLASS(parent_class)->finalize(obj);
201 }
202 
gst_shmemory_wrap_allocator_class_init(GstShMemoryWrapAllocatorClass * klass)203 static void gst_shmemory_wrap_allocator_class_init(GstShMemoryWrapAllocatorClass *klass)
204 {
205     GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
206     g_return_if_fail(gobjectClass != nullptr);
207 
208     gobjectClass->finalize = gst_shmemory_wrap_allocator_finalize;
209 
210     GstAllocatorClass *allocatorClass = GST_ALLOCATOR_CLASS(klass);
211     g_return_if_fail(allocatorClass != nullptr);
212 
213     allocatorClass->alloc = gst_shmemory_wrap_allocator_alloc;
214     allocatorClass->free = gst_shmemory_wrap_allocator_free;
215 }