1e0dac50fSopenharmony_ci/* 2e0dac50fSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License. 5e0dac50fSopenharmony_ci * You may obtain a copy of the License at 6e0dac50fSopenharmony_ci * 7e0dac50fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e0dac50fSopenharmony_ci * 9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and 13e0dac50fSopenharmony_ci * limitations under the License. 14e0dac50fSopenharmony_ci */ 15e0dac50fSopenharmony_ci 16e0dac50fSopenharmony_ci#include "surface_reader.h" 17e0dac50fSopenharmony_ci#include "sync_fence.h" 18e0dac50fSopenharmony_ci#include "window_manager_hilog.h" 19e0dac50fSopenharmony_ci#include "unique_fd.h" 20e0dac50fSopenharmony_ci 21e0dac50fSopenharmony_ci#include <securec.h> 22e0dac50fSopenharmony_ci 23e0dac50fSopenharmony_ciusing namespace OHOS::Media; 24e0dac50fSopenharmony_ci 25e0dac50fSopenharmony_cinamespace OHOS { 26e0dac50fSopenharmony_cinamespace Rosen { 27e0dac50fSopenharmony_cinamespace { 28e0dac50fSopenharmony_ciconstexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "SurfaceReader"}; 29e0dac50fSopenharmony_ci} // namespace 30e0dac50fSopenharmony_ciconst int BPP = 4; // bytes per pixel 31e0dac50fSopenharmony_ci 32e0dac50fSopenharmony_ciSurfaceReader::SurfaceReader() 33e0dac50fSopenharmony_ci{ 34e0dac50fSopenharmony_ci} 35e0dac50fSopenharmony_ci 36e0dac50fSopenharmony_ciSurfaceReader::~SurfaceReader() 37e0dac50fSopenharmony_ci{ 38e0dac50fSopenharmony_ci if (csurface_ != nullptr) { 39e0dac50fSopenharmony_ci csurface_->UnregisterConsumerListener(); 40e0dac50fSopenharmony_ci } 41e0dac50fSopenharmony_ci psurface_ = nullptr; 42e0dac50fSopenharmony_ci csurface_ = nullptr; 43e0dac50fSopenharmony_ci} 44e0dac50fSopenharmony_ci 45e0dac50fSopenharmony_cibool SurfaceReader::Init() 46e0dac50fSopenharmony_ci{ 47e0dac50fSopenharmony_ci csurface_ = IConsumerSurface::Create(); 48e0dac50fSopenharmony_ci if (csurface_ == nullptr) { 49e0dac50fSopenharmony_ci return false; 50e0dac50fSopenharmony_ci } 51e0dac50fSopenharmony_ci 52e0dac50fSopenharmony_ci auto producer = csurface_->GetProducer(); 53e0dac50fSopenharmony_ci psurface_ = Surface::CreateSurfaceAsProducer(producer); 54e0dac50fSopenharmony_ci if (psurface_ == nullptr) { 55e0dac50fSopenharmony_ci return false; 56e0dac50fSopenharmony_ci } 57e0dac50fSopenharmony_ci 58e0dac50fSopenharmony_ci listener_ = new BufferListener(*this); 59e0dac50fSopenharmony_ci SurfaceError ret = csurface_->RegisterConsumerListener(listener_); 60e0dac50fSopenharmony_ci if (ret != SURFACE_ERROR_OK) { 61e0dac50fSopenharmony_ci return false; 62e0dac50fSopenharmony_ci } 63e0dac50fSopenharmony_ci return true; 64e0dac50fSopenharmony_ci} 65e0dac50fSopenharmony_ci 66e0dac50fSopenharmony_civoid SurfaceReader::OnVsync() 67e0dac50fSopenharmony_ci{ 68e0dac50fSopenharmony_ci WLOGI("SurfaceReader::OnVsync"); 69e0dac50fSopenharmony_ci 70e0dac50fSopenharmony_ci sptr<SurfaceBuffer> cbuffer = nullptr; 71e0dac50fSopenharmony_ci int32_t fence = -1; 72e0dac50fSopenharmony_ci int64_t timestamp = 0; 73e0dac50fSopenharmony_ci Rect damage; 74e0dac50fSopenharmony_ci auto sret = csurface_->AcquireBuffer(cbuffer, fence, timestamp, damage); 75e0dac50fSopenharmony_ci sptr<SyncFence> acquireFence = new SyncFence(fence); 76e0dac50fSopenharmony_ci acquireFence->Wait(3000); // 3000ms 77e0dac50fSopenharmony_ci if (cbuffer == nullptr || sret != OHOS::SURFACE_ERROR_OK) { 78e0dac50fSopenharmony_ci WLOGFE("SurfaceReader::OnVsync: surface buffer is null"); 79e0dac50fSopenharmony_ci return; 80e0dac50fSopenharmony_ci } 81e0dac50fSopenharmony_ci 82e0dac50fSopenharmony_ci if (!ProcessBuffer(cbuffer)) { 83e0dac50fSopenharmony_ci WLOGFE("SurfaceReader::OnVsync: ProcessBuffer failed"); 84e0dac50fSopenharmony_ci return; 85e0dac50fSopenharmony_ci } 86e0dac50fSopenharmony_ci 87e0dac50fSopenharmony_ci if (cbuffer != prevBuffer_) { 88e0dac50fSopenharmony_ci if (prevBuffer_ != nullptr) { 89e0dac50fSopenharmony_ci SurfaceError ret = csurface_->ReleaseBuffer(prevBuffer_, -1); 90e0dac50fSopenharmony_ci if (ret != SURFACE_ERROR_OK) { 91e0dac50fSopenharmony_ci WLOGFE("SurfaceReader::OnVsync: release buffer error"); 92e0dac50fSopenharmony_ci return; 93e0dac50fSopenharmony_ci } 94e0dac50fSopenharmony_ci } 95e0dac50fSopenharmony_ci 96e0dac50fSopenharmony_ci prevBuffer_ = cbuffer; 97e0dac50fSopenharmony_ci } 98e0dac50fSopenharmony_ci} 99e0dac50fSopenharmony_ci 100e0dac50fSopenharmony_cisptr<Surface> SurfaceReader::GetSurface() const 101e0dac50fSopenharmony_ci{ 102e0dac50fSopenharmony_ci return psurface_; 103e0dac50fSopenharmony_ci} 104e0dac50fSopenharmony_ci 105e0dac50fSopenharmony_civoid SurfaceReader::SetHandler(sptr<SurfaceReaderHandler> handler) 106e0dac50fSopenharmony_ci{ 107e0dac50fSopenharmony_ci handler_ = handler; 108e0dac50fSopenharmony_ci} 109e0dac50fSopenharmony_ci 110e0dac50fSopenharmony_cibool SurfaceReader::ProcessBuffer(const sptr<SurfaceBuffer>& buf) 111e0dac50fSopenharmony_ci{ 112e0dac50fSopenharmony_ci if (handler_ == nullptr) { 113e0dac50fSopenharmony_ci WLOGFE("SurfaceReaderHandler not set"); 114e0dac50fSopenharmony_ci return false; 115e0dac50fSopenharmony_ci } 116e0dac50fSopenharmony_ci 117e0dac50fSopenharmony_ci BufferHandle *bufferHandle = buf->GetBufferHandle(); 118e0dac50fSopenharmony_ci if (bufferHandle == nullptr) { 119e0dac50fSopenharmony_ci WLOGFE("bufferHandle nullptr"); 120e0dac50fSopenharmony_ci return false; 121e0dac50fSopenharmony_ci } 122e0dac50fSopenharmony_ci 123e0dac50fSopenharmony_ci uint32_t width = static_cast<uint32_t>(bufferHandle->width); 124e0dac50fSopenharmony_ci uint32_t height = static_cast<uint32_t>(bufferHandle->height); 125e0dac50fSopenharmony_ci uint32_t stride = static_cast<uint32_t>(bufferHandle->stride); 126e0dac50fSopenharmony_ci uint8_t *addr = (uint8_t *)buf->GetVirAddr(); 127e0dac50fSopenharmony_ci 128e0dac50fSopenharmony_ci auto data = (uint8_t *)malloc(width * height * BPP); 129e0dac50fSopenharmony_ci if (data == nullptr) { 130e0dac50fSopenharmony_ci WLOGFE("data malloc failed"); 131e0dac50fSopenharmony_ci return false; 132e0dac50fSopenharmony_ci } 133e0dac50fSopenharmony_ci for (uint32_t i = 0; i < height; i++) { 134e0dac50fSopenharmony_ci errno_t ret = memcpy_s(data + width * i * BPP, width * BPP, addr + stride * i, width * BPP); 135e0dac50fSopenharmony_ci if (ret != EOK) { 136e0dac50fSopenharmony_ci WLOGFE("memcpy failed"); 137e0dac50fSopenharmony_ci free(data); 138e0dac50fSopenharmony_ci return false; 139e0dac50fSopenharmony_ci } 140e0dac50fSopenharmony_ci } 141e0dac50fSopenharmony_ci 142e0dac50fSopenharmony_ci Media::InitializationOptions opts; 143e0dac50fSopenharmony_ci opts.size.width = static_cast<int32_t>(width); 144e0dac50fSopenharmony_ci opts.size.height = static_cast<int32_t>(height); 145e0dac50fSopenharmony_ci std::unique_ptr<Media::PixelMap> pixelMapPtr = Media::PixelMap::Create(opts); 146e0dac50fSopenharmony_ci sptr<Media::PixelMap> pixelMap(pixelMapPtr.release()); 147e0dac50fSopenharmony_ci if (pixelMap == nullptr) { 148e0dac50fSopenharmony_ci WLOGFE("create pixelMap failed"); 149e0dac50fSopenharmony_ci free(data); 150e0dac50fSopenharmony_ci return false; 151e0dac50fSopenharmony_ci } 152e0dac50fSopenharmony_ci 153e0dac50fSopenharmony_ci ImageInfo info; 154e0dac50fSopenharmony_ci info.size.width = static_cast<int32_t>(width); 155e0dac50fSopenharmony_ci info.size.height = static_cast<int32_t>(height); 156e0dac50fSopenharmony_ci info.pixelFormat = OHOS::Media::PixelFormat::RGBA_8888; 157e0dac50fSopenharmony_ci info.colorSpace = ColorSpace::SRGB; 158e0dac50fSopenharmony_ci pixelMap->SetImageInfo(info); 159e0dac50fSopenharmony_ci 160e0dac50fSopenharmony_ci pixelMap->SetPixelsAddr(data, nullptr, width * height, AllocatorType::HEAP_ALLOC, nullptr); 161e0dac50fSopenharmony_ci 162e0dac50fSopenharmony_ci handler_->OnImageAvailable(pixelMap); 163e0dac50fSopenharmony_ci return true; 164e0dac50fSopenharmony_ci} 165e0dac50fSopenharmony_ci} 166e0dac50fSopenharmony_ci} 167