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 "buffer/avbuffer.h"
17 #include <atomic>
18 #include <iomanip>
19 #include <sstream>
20 #include "avbuffer_utils.h"
21 #include "common/log.h"
22 #include "common/status.h"
23 #include "surface_buffer.h"
24 #include "surface_type.h"
25 #include "unistd.h"
26 
27 namespace {
28 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_FOUNDATION, "AVBuffer" };
29 }
30 
31 namespace OHOS {
32 namespace Media {
AVBuffer()33 AVBuffer::AVBuffer() : pts_(0), dts_(0), duration_(0), flag_(0), meta_(nullptr), memory_(nullptr) {}
34 
~AVBuffer()35 AVBuffer::~AVBuffer() {}
36 
CreateAVBuffer(const AVBufferConfig & config)37 std::shared_ptr<AVBuffer> AVBuffer::CreateAVBuffer(const AVBufferConfig &config)
38 {
39     std::shared_ptr<AVAllocator> allocator = nullptr;
40     int32_t capacity = std::max(config.size, config.capacity);
41     MemoryFlag memflag = MemoryFlag::MEMORY_READ_WRITE;
42     switch (config.memoryType) {
43         case MemoryType::VIRTUAL_MEMORY: {
44             allocator = AVAllocatorFactory::CreateVirtualAllocator();
45             break;
46         }
47         case MemoryType::SHARED_MEMORY: {
48             memflag = config.memoryFlag;
49             allocator = AVAllocatorFactory::CreateSharedAllocator(config.memoryFlag);
50             break;
51         }
52         case MemoryType::SURFACE_MEMORY: {
53             allocator = AVAllocatorFactory::CreateSurfaceAllocator(*(config.surfaceBufferConfig));
54             break;
55         }
56         case MemoryType::HARDWARE_MEMORY: {
57             memflag = config.memoryFlag;
58             allocator = AVAllocatorFactory::CreateHardwareAllocator(config.dmaFd, capacity, config.memoryFlag);
59             break;
60         }
61         default:
62             return nullptr;
63     }
64     auto buffer = CreateAVBuffer(allocator, capacity, config.align);
65     if (buffer != nullptr) {
66         buffer->config_ = config;
67         buffer->config_.capacity = capacity;
68         buffer->config_.memoryFlag = memflag;
69     }
70     return buffer;
71 }
72 
GetConfig()73 const AVBufferConfig &AVBuffer::GetConfig()
74 {
75     FALSE_RETURN_V(memory_ != nullptr, config_);
76     config_.size = memory_->GetSize();
77     if (config_.memoryType == MemoryType::UNKNOWN_MEMORY) {
78         config_.memoryType = memory_->GetMemoryType();
79         config_.capacity = memory_->GetCapacity();
80         config_.align = memory_->align_;
81         config_.memoryFlag = memory_->GetMemoryFlag();
82         switch (config_.memoryType) {
83             case MemoryType::VIRTUAL_MEMORY: {
84                 break;
85             }
86             case MemoryType::SHARED_MEMORY: {
87                 break;
88             }
89             case MemoryType::HARDWARE_MEMORY: {
90                 config_.dmaFd = memory_->GetFileDescriptor();
91                 break;
92             }
93             case MemoryType::SURFACE_MEMORY: {
94                 auto surfaceBuffer = memory_->GetSurfaceBuffer();
95                 config_.surfaceBufferConfig->width = surfaceBuffer->GetWidth();
96                 config_.surfaceBufferConfig->height = surfaceBuffer->GetHeight();
97                 config_.surfaceBufferConfig->strideAlignment = surfaceBuffer->GetStride();
98                 config_.surfaceBufferConfig->format = surfaceBuffer->GetFormat();
99                 config_.surfaceBufferConfig->usage = surfaceBuffer->GetUsage();
100                 config_.surfaceBufferConfig->colorGamut = surfaceBuffer->GetSurfaceBufferColorGamut();
101                 config_.surfaceBufferConfig->transform = surfaceBuffer->GetSurfaceBufferTransform();
102                 break;
103             }
104             default:
105                 break;
106         }
107     }
108     return config_;
109 }
110 
CreateAVBuffer(std::shared_ptr<AVAllocator> allocator,int32_t capacity,int32_t align)111 std::shared_ptr<AVBuffer> AVBuffer::CreateAVBuffer(std::shared_ptr<AVAllocator> allocator, int32_t capacity,
112                                                    int32_t align)
113 {
114     FALSE_RETURN_V_MSG_E(allocator != nullptr, nullptr, "allocator is nullptr");
115     FALSE_RETURN_V_MSG_E(capacity >= 0, nullptr, "capacity is invalid");
116     FALSE_RETURN_V_MSG_E(align >= 0, nullptr, "align is invalid");
117 
118     auto buffer = std::shared_ptr<AVBuffer>(new AVBuffer());
119     FALSE_RETURN_V_MSG_E(buffer != nullptr, nullptr, "Create AVBuffer failed, no memory");
120 
121     Status ret = buffer->Init(allocator, capacity, align);
122     FALSE_RETURN_V_MSG_E(ret == Status::OK, nullptr, "Init AVBuffer failed");
123 
124     buffer->meta_ = std::make_shared<Meta>();
125     FALSE_RETURN_V_MSG_E(buffer->meta_ != nullptr, nullptr, "Create meta_ failed, no memory");
126     return buffer;
127 }
128 
CreateAVBuffer(uint8_t * ptr,int32_t capacity,int32_t size)129 std::shared_ptr<AVBuffer> AVBuffer::CreateAVBuffer(uint8_t *ptr, int32_t capacity, int32_t size)
130 {
131     FALSE_RETURN_V_MSG_E(ptr != nullptr, nullptr, "ptr is nullptr");
132     FALSE_RETURN_V_MSG_E(capacity >= 0, nullptr, "capacity is invalid");
133     FALSE_RETURN_V_MSG_E((0 <= size) && (size <= capacity), nullptr, "size is invalid");
134 
135     auto buffer = std::shared_ptr<AVBuffer>(new AVBuffer());
136     FALSE_RETURN_V_MSG_E(buffer != nullptr, nullptr, "Create AVBuffer failed, no memory");
137 
138     buffer->meta_ = std::make_shared<Meta>();
139     FALSE_RETURN_V_MSG_E(buffer->meta_ != nullptr, nullptr, "Create meta_ failed, no memory");
140 
141     Status ret = buffer->Init(ptr, capacity, size);
142     FALSE_RETURN_V_MSG_E(ret == Status::OK, nullptr, "Init AVBuffer failed");
143     return buffer;
144 }
145 
CreateAVBuffer(sptr<SurfaceBuffer> surfaceBuffer)146 std::shared_ptr<AVBuffer> AVBuffer::CreateAVBuffer(sptr<SurfaceBuffer> surfaceBuffer)
147 {
148     FALSE_RETURN_V_MSG_E(surfaceBuffer != nullptr, nullptr, "surfaceBuffer is nullptr");
149     FALSE_RETURN_V_MSG_E(surfaceBuffer->GetSptrRefCount() > 0, nullptr, "GetSptrRefCount is invalid, count:%{public}d",
150                          surfaceBuffer->GetSptrRefCount());
151 
152     auto buffer = std::shared_ptr<AVBuffer>(new AVBuffer());
153     FALSE_RETURN_V_MSG_E(buffer != nullptr, nullptr, "Create AVBuffer failed, no memory");
154 
155     buffer->meta_ = std::make_shared<Meta>();
156     FALSE_RETURN_V_MSG_E(buffer->meta_ != nullptr, nullptr, "Create meta_ failed, no memory");
157 
158     Status ret = buffer->Init(surfaceBuffer);
159     FALSE_RETURN_V_MSG_E(ret == Status::OK, nullptr, "Init AVBuffer failed");
160     return buffer;
161 }
162 
CreateAVBuffer()163 std::shared_ptr<AVBuffer> AVBuffer::CreateAVBuffer()
164 {
165     auto buffer = std::shared_ptr<AVBuffer>(new AVBuffer());
166     FALSE_RETURN_V_MSG_E(buffer != nullptr, nullptr, "Create AVBuffer failed, no memory");
167 
168     buffer->meta_ = std::make_shared<Meta>();
169     FALSE_RETURN_V_MSG_E(buffer->meta_ != nullptr, nullptr, "Create meta_ failed, no memory");
170     return buffer;
171 }
172 
Init(std::shared_ptr<AVAllocator> allocator,int32_t capacity,int32_t align)173 Status AVBuffer::Init(std::shared_ptr<AVAllocator> allocator, int32_t capacity, int32_t align)
174 {
175     memory_ = AVMemory::CreateAVMemory(allocator, capacity, align);
176     FALSE_RETURN_V_MSG_E(memory_ != nullptr, Status::ERROR_UNKNOWN, "Create memory failed");
177     return Status::OK;
178 }
179 
Init(uint8_t * ptr,int32_t capacity,int32_t size)180 Status AVBuffer::Init(uint8_t *ptr, int32_t capacity, int32_t size)
181 {
182     memory_ = AVMemory::CreateAVMemory(ptr, capacity, size);
183     FALSE_RETURN_V_MSG_E(memory_ != nullptr, Status::ERROR_UNKNOWN, "Create memory failed");
184     return Status::OK;
185 }
186 
Init(sptr<SurfaceBuffer> surfaceBuffer)187 Status AVBuffer::Init(sptr<SurfaceBuffer> surfaceBuffer)
188 {
189     memory_ = AVMemory::CreateAVMemory(surfaceBuffer);
190     FALSE_RETURN_V_MSG_E(memory_ != nullptr, Status::ERROR_UNKNOWN, "Create memory failed");
191     return Status::OK;
192 }
193 
GetUniqueId()194 uint64_t AVBuffer::GetUniqueId()
195 {
196     if (memory_ == nullptr) {
197         return 0;
198     }
199     return memory_->uid_;
200 }
201 
WriteToMessageParcel(MessageParcel & parcel)202 bool AVBuffer::WriteToMessageParcel(MessageParcel &parcel)
203 {
204 #ifdef MEDIA_OHOS
205     MessageParcel bufferParcel;
206     bool ret = bufferParcel.WriteUint64(GetUniqueId()) && bufferParcel.WriteInt64(pts_) &&
207                bufferParcel.WriteInt64(dts_) && bufferParcel.WriteInt64(duration_) && bufferParcel.WriteUint32(flag_) &&
208                meta_->ToParcel(bufferParcel);
209 
210     if (memory_ != nullptr) {
211         MemoryType type = memory_->GetMemoryType();
212         FALSE_RETURN_V_MSG_E(type != MemoryType::VIRTUAL_MEMORY, false, "Virtual memory not support");
213 
214         ret = ret && bufferParcel.WriteUint8(static_cast<uint8_t>(type)) &&
215               memory_->WriteCommonToMessageParcel(bufferParcel) && memory_->WriteToMessageParcel(bufferParcel);
216     }
217     if (ret) {
218         parcel.Append(bufferParcel);
219     }
220     return ret;
221 #else
222     return false;
223 #endif
224 }
225 
ReadFromMessageParcel(MessageParcel & parcel,bool isSurfaceBuffer)226 bool AVBuffer::ReadFromMessageParcel(MessageParcel &parcel, bool isSurfaceBuffer)
227 {
228 #ifdef MEDIA_OHOS
229     if (isSurfaceBuffer) {
230         FALSE_RETURN_V(memory_ == nullptr, false);
231         memory_ = AVMemory::CreateAVMemory(parcel, true);
232         FALSE_RETURN_V_MSG_E(memory_ != nullptr, false, "Create memory failed");
233         return true;
234     }
235     // 1. 不同buffer更新attr:  memroy != nullptr,uid != fromParcel, 返回错误
236     // 2. 相同buffer更新attr:  memroy != nullptr,uid == fromParcel,不创建memory,更新attr + memory的attr
237     // 3. 初始化buffer:        memroy == nullptr,fromParcel != 0,创建memory
238     // 4. 只传buffer的attr:    memroy == nullptr,fromParcel == 0,更新attr
239     uint64_t uid = 0;
240     int64_t pts = 0;
241     int64_t dts = 0;
242     int64_t duration = 0;
243     uint32_t flag = 0;
244     Meta meta;
245     bool ret = parcel.ReadUint64(uid) && parcel.ReadInt64(pts) && parcel.ReadInt64(dts) &&
246                parcel.ReadInt64(duration) && parcel.ReadUint32(flag) && meta.FromParcel(parcel);
247     FALSE_RETURN_V_MSG_E(ret, false, "Unmarshalling buffer info failed");
248 
249     if (memory_ != nullptr) {
250         FALSE_RETURN_V_MSG_E(GetUniqueId() == uid, false, "Can't read message parcel from other AVBuffer object!");
251         (void)parcel.ReadUint8();
252         ret = memory_->SkipCommonFromMessageParcel(parcel) && memory_->ReadFromMessageParcel(parcel);
253         FALSE_RETURN_V_MSG_E(ret, false, "Update memory info failed");
254     } else if (uid != 0) {
255         memory_ = AVMemory::CreateAVMemory(parcel, false);
256         FALSE_RETURN_V_MSG_E(memory_ != nullptr, false, "Create memory failed");
257         memory_->uid_ = uid;
258     }
259     pts_ = pts;
260     dts_ = dts;
261     duration_ = duration;
262     flag_ = flag;
263     if (meta_ == nullptr) {
264         meta_ = std::make_shared<Meta>();
265     }
266     *meta_ = std::move(meta);
267 #endif
268     return true;
269 }
270 } // namespace Media
271 } // namespace OHOS