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