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