• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 #include "av_hardware_memory.h"
17 #include "av_shared_memory_ext.h"
18 #include "av_surface_memory.h"
19 #include "av_virtual_memory.h"
20 #include "buffer/avallocator.h"
21 #include "buffer/avbuffer.h"
22 #include "common/log.h"
23 #include "common/status.h"
24 #include "message_parcel.h"
25 #include "securec.h"
26 #include "surface_buffer.h"
27 
28 namespace {
GetUniqueId()29 uint64_t GetUniqueId()
30 {
31 #ifdef MEDIA_OHOS
32     using namespace std::chrono;
33     static const uint64_t startTime = time_point_cast<seconds>(system_clock::now()).time_since_epoch().count();
34     static const uint16_t processId = static_cast<uint16_t>(getpid());
35 #else
36     static const uint64_t startTime = 0;
37     static const uint16_t processId = 0;
38 #endif
39     static std::atomic<uint32_t> bufferId = 0;
40     if (bufferId == UINT32_MAX) {
41         bufferId = 0;
42     }
43     union UniqueId {
44         uint64_t startTime;    //  1--16, 16: time
45         uint16_t processId[4]; // 17--32, 16: process id
46         uint32_t bufferId[2];  // 33--64, 32: atomic val
47     } uid = {.startTime = startTime};
48     ++bufferId;
49     uid.processId[1] = processId;
50     uid.bufferId[1] = bufferId;
51     return uid.startTime;
52 }
53 
54 } // namespace
55 namespace OHOS {
56 namespace Media {
CreateAVMemory(std::shared_ptr<AVAllocator> allocator,int32_t capacity,int32_t align)57 std::shared_ptr<AVMemory> AVMemory::CreateAVMemory(std::shared_ptr<AVAllocator> allocator, int32_t capacity,
58                                                    int32_t align)
59 {
60     MemoryType type = allocator->GetMemoryType();
61     std::shared_ptr<AVMemory> mem = nullptr;
62     switch (type) {
63         case MemoryType::VIRTUAL_MEMORY: {
64             mem = std::shared_ptr<AVMemory>(new AVVirtualMemory());
65             break;
66         }
67         case MemoryType::SURFACE_MEMORY: {
68             mem = std::shared_ptr<AVMemory>(new AVSurfaceMemory());
69             break;
70         }
71         case MemoryType::SHARED_MEMORY: {
72             mem = std::shared_ptr<AVMemory>(new AVSharedMemoryExt());
73             break;
74         }
75         case MemoryType::HARDWARE_MEMORY: {
76             mem = std::shared_ptr<AVMemory>(new AVHardwareMemory());
77             break;
78         }
79         default:
80             break;
81     }
82     FALSE_RETURN_V_MSG_E(mem != nullptr, nullptr, "Create AVMemory failed, no memory");
83 
84     mem->allocator_ = allocator;
85     mem->capacity_ = capacity;
86     mem->align_ = align;
87     Status ret = mem->Init();
88     FALSE_RETURN_V_MSG_E(ret == Status::OK, nullptr, "Init AVMemory failed, uid:" PUBLIC_LOG_U64, mem->uid_);
89     return mem;
90 }
91 
CreateAVMemory(uint8_t * ptr,int32_t capacity,int32_t size)92 std::shared_ptr<AVMemory> AVMemory::CreateAVMemory(uint8_t *ptr, int32_t capacity, int32_t size)
93 {
94     std::shared_ptr<AVMemory> mem = std::shared_ptr<AVMemory>(new AVVirtualMemory());
95     FALSE_RETURN_V_MSG_E(mem != nullptr, nullptr, "Create AVVirtualMemory failed, no memory");
96     mem->allocator_ = nullptr;
97     mem->capacity_ = capacity;
98     mem->size_ = size;
99     mem->base_ = ptr;
100     return mem;
101 }
102 
CreateAVMemory(MessageParcel & parcel,bool isSurfaceBuffer)103 std::shared_ptr<AVMemory> AVMemory::CreateAVMemory(MessageParcel &parcel, bool isSurfaceBuffer)
104 {
105 #ifdef MEDIA_OHOS
106     if (isSurfaceBuffer) {
107         auto mem = std::shared_ptr<AVMemory>(new AVSurfaceMemory());
108         Status ret = mem->InitSurfaceBuffer(parcel);
109         FALSE_RETURN_V_MSG_E(ret == Status::OK, nullptr, "Init AVSurfaceMemory failed");
110         return mem;
111     }
112     MemoryType type = static_cast<MemoryType>(parcel.ReadUint8());
113     std::shared_ptr<AVMemory> mem = nullptr;
114     switch (type) {
115         case MemoryType::VIRTUAL_MEMORY: {
116             return nullptr;
117         }
118         case MemoryType::SURFACE_MEMORY: {
119             mem = std::shared_ptr<AVMemory>(new AVSurfaceMemory());
120             break;
121         }
122         case MemoryType::SHARED_MEMORY: {
123             mem = std::shared_ptr<AVMemory>(new AVSharedMemoryExt());
124             break;
125         }
126         case MemoryType::HARDWARE_MEMORY: {
127             mem = std::shared_ptr<AVMemory>(new AVHardwareMemory());
128             break;
129         }
130         default:
131             break;
132     }
133 
134     FALSE_RETURN_V_MSG_E(mem != nullptr, nullptr, "Create AVMemory failed, no memory");
135     bool isReadParcel = mem->ReadCommonFromMessageParcel(parcel);
136     FALSE_RETURN_V_MSG_E(isReadParcel == true, nullptr, "Read common memory info from parcel failed");
137 
138     Status ret = mem->Init(parcel);
139     FALSE_RETURN_V_MSG_E(ret == Status::OK, nullptr, "Init AVMemory failed, uid:" PUBLIC_LOG_U64, mem->uid_);
140     return mem;
141 #else
142     return nullptr;
143 #endif
144 }
145 
CreateAVMemory(sptr<SurfaceBuffer> surfaceBuffer)146 std::shared_ptr<AVMemory> AVMemory::CreateAVMemory(sptr<SurfaceBuffer> surfaceBuffer)
147 {
148     auto mem = std::shared_ptr<AVMemory>(new AVSurfaceMemory());
149     Status ret = mem->InitSurfaceBuffer(surfaceBuffer);
150     FALSE_RETURN_V_MSG_E(ret == Status::OK, nullptr, "Init AVSurfaceMemory failed");
151     return mem;
152 }
153 
AVMemory()154 AVMemory::AVMemory() : align_(0), offset_(0), size_(0), base_(nullptr), uid_(GetUniqueId()), allocator_(nullptr)
155 {
156     MEDIA_LOG_DD("enter ctor, instance:0x%{public}06" PRIXPTR ", uid:" PUBLIC_LOG_U64, FAKE_POINTER(this), uid_);
157 }
158 
~AVMemory()159 AVMemory::~AVMemory()
160 {
161     MEDIA_LOG_DD("enter dtor, instance:0x%{public}06" PRIXPTR ", uid:" PUBLIC_LOG_U64, FAKE_POINTER(this), uid_);
162 }
163 
Init()164 Status AVMemory::Init()
165 {
166     return Status::ERROR_UNIMPLEMENTED;
167 }
168 
Init(MessageParcel & parcel)169 Status AVMemory::Init(MessageParcel &parcel)
170 {
171     (void)parcel;
172     return Status::ERROR_UNIMPLEMENTED;
173 }
174 
InitSurfaceBuffer(MessageParcel & parcel)175 Status AVMemory::InitSurfaceBuffer(MessageParcel &parcel)
176 {
177     (void)parcel;
178     return Status::ERROR_UNIMPLEMENTED;
179 }
180 
InitSurfaceBuffer(sptr<SurfaceBuffer> surfaceBuffer)181 Status AVMemory::InitSurfaceBuffer(sptr<SurfaceBuffer> surfaceBuffer)
182 {
183     (void)surfaceBuffer;
184     return Status::ERROR_UNIMPLEMENTED;
185 }
186 
ReadFromMessageParcel(MessageParcel & parcel)187 bool AVMemory::ReadFromMessageParcel(MessageParcel &parcel)
188 {
189     (void)parcel;
190     return false;
191 }
192 
WriteToMessageParcel(MessageParcel & parcel)193 bool AVMemory::WriteToMessageParcel(MessageParcel &parcel)
194 {
195     (void)parcel;
196     return false;
197 }
198 
ReadCommonFromMessageParcel(MessageParcel & parcel)199 bool AVMemory::ReadCommonFromMessageParcel(MessageParcel &parcel)
200 {
201 #ifdef MEDIA_OHOS
202     (void)parcel.ReadUint64();
203     int32_t capacity = -1;
204     int32_t align = -1;
205     int32_t offset = -1;
206     int32_t size = -1;
207 
208     bool ret = parcel.ReadInt32(capacity);
209     FALSE_RETURN_V_MSG_E(ret && (capacity >= 0), false, "capacity is invalid");
210 
211     ret = parcel.ReadInt32(align);
212     FALSE_RETURN_V_MSG_E(ret && (capacity >= align) && (align >= 0), false, "align is invalid");
213 
214     ret = parcel.ReadInt32(offset);
215     FALSE_RETURN_V_MSG_E(ret && (capacity >= offset) && (offset >= 0), false, "offset is invalid");
216 
217     ret = parcel.ReadInt32(size);
218     FALSE_RETURN_V_MSG_E(ret && (capacity >= size) && (size >= 0), false, "size is invalid");
219 
220     capacity_ = capacity;
221     align_ = align;
222     offset_ = offset;
223     size_ = size;
224     return true;
225 #else
226     return true;
227 #endif
228 }
229 
SkipCommonFromMessageParcel(MessageParcel & parcel)230 bool AVMemory::SkipCommonFromMessageParcel(MessageParcel &parcel)
231 {
232 #ifdef MEDIA_OHOS
233     uint64_t skipSize = 0;
234     bool ret = parcel.ReadUint64(skipSize);
235     FALSE_RETURN_V_MSG_E(ret, false, "unknown parcel");
236     parcel.SkipBytes(static_cast<size_t>(skipSize) - 2 * sizeof(int32_t)); // 2: the size of size_ and offset_
237 
238     int32_t size = -1;
239     int32_t offset = -1;
240 
241     ret = parcel.ReadInt32(offset);
242     FALSE_RETURN_V_MSG_E(ret && (capacity_ >= offset) && (offset >= 0), false, "offset is invalid");
243 
244     ret = parcel.ReadInt32(size);
245     FALSE_RETURN_V_MSG_E(ret && (capacity_ >= size) && (size >= 0), false, "size is invalid");
246 
247     size_ = size;
248     offset_ = offset;
249     return true;
250 #else
251     return true;
252 #endif
253 }
254 
WriteCommonToMessageParcel(MessageParcel & parcel)255 bool AVMemory::WriteCommonToMessageParcel(MessageParcel &parcel)
256 {
257 #ifdef MEDIA_OHOS
258     bool ret = true;
259     MessageParcel bufferParcel;
260     ret = bufferParcel.WriteInt32(capacity_) && bufferParcel.WriteInt32(align_) && bufferParcel.WriteInt32(offset_) &&
261           bufferParcel.WriteInt32(size_);
262 
263     size_t size = bufferParcel.GetDataSize();
264     return ret && parcel.WriteUint64(static_cast<uint64_t>(size)) && parcel.Append(bufferParcel);
265 #endif
266     return true;
267 }
268 
GetMemoryType()269 MemoryType AVMemory::GetMemoryType()
270 {
271     return MemoryType::VIRTUAL_MEMORY;
272 }
273 
GetMemoryFlag()274 MemoryFlag AVMemory::GetMemoryFlag()
275 {
276     return MemoryFlag::MEMORY_READ_WRITE;
277 }
278 
GetCapacity()279 int32_t AVMemory::GetCapacity()
280 {
281     return capacity_;
282 }
283 
GetSize()284 int32_t AVMemory::GetSize()
285 {
286     return size_;
287 }
288 
SetSize(int32_t size)289 Status AVMemory::SetSize(int32_t size)
290 {
291     FALSE_RETURN_V_MSG_E((capacity_ >= size) && (size >= 0), Status::ERROR_INVALID_PARAMETER,
292                          "size out of range, "
293                          "current size:%{public}d , capacity:%{public}d",
294                          size_, capacity_);
295     size_ = size;
296     return Status::OK;
297 }
298 
GetOffset()299 int32_t AVMemory::GetOffset()
300 {
301     return offset_;
302 }
303 
SetOffset(int32_t offset)304 Status AVMemory::SetOffset(int32_t offset)
305 {
306     FALSE_RETURN_V_MSG_E((capacity_ >= offset) && (offset >= 0), Status::ERROR_INVALID_PARAMETER,
307                          "offset out of range, "
308                          "current offset:%{public}d , capacity:%{public}d",
309                          offset_, capacity_);
310     offset_ = offset;
311     return Status::OK;
312 }
313 
GetAddr()314 uint8_t *AVMemory::GetAddr()
315 {
316     return base_;
317 }
318 
GetFileDescriptor()319 int32_t AVMemory::GetFileDescriptor()
320 {
321     return -1;
322 }
323 
Write(const uint8_t * in,int32_t writeSize,int32_t position)324 int32_t AVMemory::Write(const uint8_t *in, int32_t writeSize, int32_t position)
325 {
326     FALSE_RETURN_V_MSG_E(in != nullptr, 0, "Input buffer is nullptr");
327     FALSE_RETURN_V_MSG_E(writeSize > 0, 0, "Input writeSize:%{public}d is invalid", writeSize);
328     FALSE_RETURN_V_MSG_E((GetMemoryFlag() & MemoryFlag::MEMORY_WRITE_ONLY) != 0, 0, "Lack write permission");
329     uint8_t *addr = GetAddr();
330     FALSE_RETURN_V_MSG_E(addr != nullptr, 0, "Base buffer is nullptr");
331     int32_t start = 0;
332     if (position <= INVALID_POSITION) {
333         start = size_;
334     } else {
335         start = std::min(position, capacity_);
336     }
337     int32_t unusedSize = capacity_ - start;
338     int32_t length = std::min(writeSize, unusedSize);
339     FALSE_RETURN_V_MSG_E((length + start) <= capacity_, 0,
340                          "Write out of bounds, length:%{public}d , start:%{public}d , capacity:%{public}d", length,
341                          start, capacity_);
342     uint8_t *dstPtr = addr + start;
343     FALSE_RETURN_V_MSG_E(dstPtr != nullptr, 0, "Inner dstPtr is nullptr");
344     auto error = memcpy_s(dstPtr, length, in, length);
345     FALSE_RETURN_V_MSG_E(error == EOK, 0, "Inner memcpy_s failed, uid:" PUBLIC_LOG_U64 ", %{public}s", uid_,
346                          strerror(error));
347     size_ = start + length;
348     return length;
349 }
350 
Read(uint8_t * out,int32_t readSize,int32_t position)351 int32_t AVMemory::Read(uint8_t *out, int32_t readSize, int32_t position)
352 {
353     FALSE_RETURN_V_MSG_E(out != nullptr, 0, "Output buffer is nullptr");
354     FALSE_RETURN_V_MSG_E(readSize > 0, 0, "Output readSize:%{public}d is invalid", readSize);
355     FALSE_RETURN_V_MSG_E((GetMemoryFlag() & MemoryFlag::MEMORY_READ_ONLY) != 0, 0, "Lack read permission");
356     uint8_t *addr = GetAddr();
357     FALSE_RETURN_V_MSG_E(addr != nullptr, 0, "Base buffer is nullptr");
358     int32_t start = 0;
359     size_t maxLength = size_;
360     if (position > INVALID_POSITION) {
361         start = std::min(position, size_);
362         maxLength = size_ - start;
363     }
364     int32_t length = std::min(static_cast<size_t>(readSize), maxLength);
365     FALSE_RETURN_V_MSG_E((length + start) <= capacity_, 0,
366                          "Read out of bounds, length:%{public}d, start:%{public}d, capacity:%{public}d", length, start,
367                          capacity_);
368     uint8_t *srcPtr = addr + start;
369     FALSE_RETURN_V_MSG_E(srcPtr != nullptr, 0, "Inner srcPtr is nullptr");
370     auto error = memcpy_s(out, length, srcPtr, length);
371     FALSE_RETURN_V_MSG_E(error == EOK, 0, "Inner memcpy_s failed, uid:%" PUBLIC_LOG_U64 ", %{public}s", uid_,
372                          strerror(error));
373     return length;
374 }
375 
Reset()376 void AVMemory::Reset()
377 {
378     size_ = 0;
379 }
380 
GetSurfaceBuffer()381 sptr<SurfaceBuffer> AVMemory::GetSurfaceBuffer()
382 {
383     return nullptr;
384 }
385 } // namespace Media
386 } // namespace OHOS