1/* 2 * Copyright (c) 2021-2021 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#if !defined(OHOS_LITE) && defined(VIDEO_SUPPORT) 17#include "plugin/common/surface_memory.h" 18#include <utility> 19#include "foundation/log.h" 20#include "plugin/common/surface_allocator.h" 21 22namespace OHOS { 23namespace Media { 24namespace Plugin { 25SurfaceMemory::SurfaceMemory(size_t capacity, std::shared_ptr<Allocator> allocator, size_t align) 26 : Memory(capacity, std::move(allocator), align, MemoryType::SURFACE_BUFFER, false), 27 fence_(-1), 28 stride_(0) 29{ 30 MEDIA_LOG_DD("SurfaceMemory ctor."); 31 if (this->allocator != nullptr && this->allocator->GetMemoryType() == MemoryType::SURFACE_BUFFER) { 32 surfaceAllocator_ = ReinterpretPointerCast<SurfaceAllocator>(this->allocator); 33 AllocSurfaceBuffer(); 34 } 35} 36 37SurfaceMemory::SurfaceMemory(sptr<SurfaceBuffer> surfaceBuffer, int32_t surfaceCapacity) 38 : Memory(surfaceCapacity, nullptr, 1, MemoryType::SURFACE_BUFFER, false), // align 1 39 surfaceBuffer_(surfaceBuffer), fence_(-1), stride_(0) 40{ 41} 42 43SurfaceMemory::~SurfaceMemory() 44{ 45 MEDIA_LOG_DD("SurfaceMemory dtor."); 46 ReleaseSurfaceBuffer(); 47} 48 49void SurfaceMemory::AllocSurfaceBuffer() 50{ 51 if (surfaceAllocator_ == nullptr || surfaceBuffer_ != nullptr) { 52 MEDIA_LOG_E("No need to allocate surface buffer."); 53 return; 54 } 55 surfaceBuffer_ = surfaceAllocator_->AllocSurfaceBuffer(); 56 if (surfaceBuffer_ != nullptr) { 57 auto bufferHandle = surfaceBuffer_->GetBufferHandle(); 58 if (bufferHandle != nullptr) { 59 stride_ = bufferHandle->stride; 60 } 61 fence_ = -1; 62 } else { 63 // Surface often obtain buffer failed, but doesn't cause any problem. 64 MEDIA_LOG_DD("AllocSurfaceBuffer failed."); 65 } 66} 67 68sptr<SurfaceBuffer> SurfaceMemory::GetSurfaceBuffer() 69{ 70 OSAL::ScopedLock l(memMutex_); 71 if (!surfaceBuffer_ || needRender_) { 72 // request surface buffer again when old buffer flush to nullptr 73 surfaceBuffer_ = nullptr; 74 AllocSurfaceBuffer(); 75 needRender_ = false; 76 } 77 return surfaceBuffer_; 78} 79 80void SurfaceMemory::ReleaseSurfaceBuffer() 81{ 82 OSAL::ScopedLock l(memMutex_); 83 if (surfaceBuffer_ != nullptr && surfaceAllocator_) { 84 surfaceAllocator_->ReleaseSurfaceBuffer(surfaceBuffer_, needRender_); 85 } 86} 87 88int32_t SurfaceMemory::GetFlushFence() 89{ 90 OSAL::ScopedLock l(memMutex_); 91 return fence_; 92} 93 94BufferHandle *SurfaceMemory::GetBufferHandle() 95{ 96 OSAL::ScopedLock l(memMutex_); 97 if (surfaceBuffer_) { 98 return surfaceBuffer_->GetBufferHandle(); 99 } 100 return nullptr; 101} 102 103void SurfaceMemory::SetNeedRender(bool needRender) 104{ 105 OSAL::ScopedLock l(memMutex_); 106 needRender_ = needRender; 107} 108 109uint32_t SurfaceMemory::GetSurfaceBufferStride() 110{ 111 OSAL::ScopedLock l(memMutex_); 112 return stride_; 113} 114 115uint8_t* SurfaceMemory::GetRealAddr() const 116{ 117 OSAL::ScopedLock l(memMutex_); 118 if (surfaceBuffer_) { 119 return static_cast<uint8_t *>(surfaceBuffer_->GetVirAddr()); 120 } 121 return nullptr; 122} 123} // namespace Plugin 124} // namespace Media 125} // namespace OHOS 126#endif