1 /* 2 * Copyright (C) 2022 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 "image_receiver.h" 17 #include "image_packer.h" 18 #include "image_source.h" 19 #include "image_utils.h" 20 #include "hilog/log.h" 21 #include "image_receiver_manager.h" 22 23 namespace OHOS { 24 namespace Media { 25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "imageReceiver"}; 26 using namespace OHOS::HiviewDFX; 27 28 enum class mode_ { 29 MODE_PREVIEW = 0, 30 MODE_PHOTO 31 }; 32 PackImage(int & fd,std::unique_ptr<PixelMap> pixelMap)33 int64_t PackImage(int &fd, std::unique_ptr<PixelMap> pixelMap) 34 { 35 HiLog::Debug(LABEL, "PackImage"); 36 ImagePacker imagePacker; 37 PackOption option; 38 option.format = ImageReceiver::OPTION_FORMAT; 39 option.quality = ImageReceiver::OPTION_QUALITY; 40 option.numberHint = ImageReceiver::OPTION_NUMBERHINT; 41 std::set<std::string> formats; 42 if (pixelMap == nullptr) { 43 HiLog::Error(LABEL, "pixelMap is nullptr"); 44 return 0; 45 } 46 uint32_t ret = imagePacker.GetSupportedFormats(formats); 47 if (ret != SUCCESS) { 48 HiLog::Error(LABEL, "image packer get supported format failed, ret=%{public}u.", ret); 49 return 0; 50 } else { 51 HiLog::Debug(LABEL, "SUCCESS"); 52 } 53 imagePacker.StartPacking(fd, option); 54 imagePacker.AddImage(*pixelMap); 55 int64_t packedSize = 0; 56 imagePacker.FinalizePacking(packedSize); 57 HiLog::Debug(LABEL, "packedSize=%{public}lld.", static_cast<long long>(packedSize)); 58 HiLog::Debug(LABEL, "packedSize=%{public}lld.", static_cast<long long>(packedSize)); 59 return packedSize; 60 } 61 getSurfacePixelMap(InitializationOptions initializationOpts)62 std::unique_ptr<PixelMap> ImageReceiver::getSurfacePixelMap(InitializationOptions initializationOpts) 63 { 64 uint32_t *addr = reinterpret_cast<uint32_t *>(iraContext_->currentBuffer_->GetVirAddr()); 65 int32_t size = iraContext_->currentBuffer_->GetSize(); 66 return PixelMap::Create(addr, (uint32_t)size, initializationOpts); 67 } 68 SaveSTP(uint32_t * buffer,uint32_t bufferSize,int & fd,InitializationOptions initializationOpts)69 static int32_t SaveSTP(uint32_t *buffer, 70 uint32_t bufferSize, 71 int &fd, 72 InitializationOptions initializationOpts) 73 { 74 int64_t errorCode = -1; 75 std::unique_ptr<PixelMap> pixelMap = PixelMap::Create(buffer, bufferSize, initializationOpts); 76 if (pixelMap.get() != nullptr) { 77 ImageInfo imageInfo; 78 pixelMap->GetImageInfo(imageInfo); 79 HiLog::Debug(LABEL, "create pixel map imageInfo.size.width=%{public}u.", imageInfo.size.width); 80 } else { 81 HiLog::Error(LABEL, "pixelMap.get() == nullptr"); 82 return ERR_MEDIA_INVALID_VALUE; 83 } 84 ImagePacker imagePacker; 85 errorCode = PackImage(fd, std::move(pixelMap)); 86 if (errorCode > 0) { 87 errorCode = SUCCESS; 88 } else { 89 errorCode = ERR_MEDIA_INVALID_VALUE; 90 } 91 return errorCode; 92 } 93 SaveBufferAsImage(int & fd,OHOS::sptr<OHOS::SurfaceBuffer> buffer,InitializationOptions initializationOpts)94 int32_t ImageReceiver::SaveBufferAsImage(int &fd, 95 OHOS::sptr<OHOS::SurfaceBuffer> buffer, 96 InitializationOptions initializationOpts) 97 { 98 int32_t errorcode = 0; 99 if (buffer != nullptr) { 100 uint32_t *addr = reinterpret_cast<uint32_t *>(buffer->GetVirAddr()); 101 int32_t size = buffer->GetSize(); 102 errorcode = SaveSTP(addr, (uint32_t)size, fd, initializationOpts); 103 if ((iraContext_->GetReceiverBufferConsumer()) != nullptr) { 104 (iraContext_->GetReceiverBufferConsumer())->ReleaseBuffer(buffer, -1); 105 } else { 106 HiLog::Debug(LABEL, "iraContext_->GetReceiverBufferConsumer() == nullptr"); 107 } 108 } else { 109 HiLog::Debug(LABEL, "SaveBufferAsImage buffer == nullptr"); 110 } 111 return errorcode; 112 } 113 SaveBufferAsImage(int & fd,InitializationOptions initializationOpts)114 int32_t ImageReceiver::SaveBufferAsImage(int &fd, 115 InitializationOptions initializationOpts) 116 { 117 if (iraContext_->currentBuffer_ != nullptr) { 118 return SaveBufferAsImage(fd, iraContext_->currentBuffer_, initializationOpts); 119 } 120 HiLog::Debug(LABEL, "iraContext_->GetCurrentBuffer() == nullptr"); 121 return 0; 122 } 123 ReleaseBuffer(OHOS::sptr<OHOS::SurfaceBuffer> & buffer)124 void ImageReceiver::ReleaseBuffer(OHOS::sptr<OHOS::SurfaceBuffer> &buffer) 125 { 126 if (buffer != nullptr) { 127 if (iraContext_ != nullptr) { 128 auto listenerConsumerSurface = iraContext_->GetReceiverBufferConsumer(); 129 if (listenerConsumerSurface != nullptr) { 130 listenerConsumerSurface->ReleaseBuffer(buffer, -1); 131 } else { 132 HiLog::Debug(LABEL, "listenerConsumerSurface == nullptr"); 133 } 134 } else { 135 HiLog::Debug(LABEL, "iraContext_ == nullptr"); 136 } 137 buffer = nullptr; 138 } 139 } 140 OnBufferAvailable()141 void ImageReceiverSurfaceListener ::OnBufferAvailable() 142 { 143 HiLog::Debug(LABEL, "OnBufferAvailable"); 144 if (ir_->surfaceBufferAvaliableListener_ != nullptr) { 145 ir_->surfaceBufferAvaliableListener_->OnSurfaceBufferAvaliable(); 146 } 147 } 148 CreateImageReceiverContext()149 std::shared_ptr<ImageReceiverContext> ImageReceiverContext ::CreateImageReceiverContext() 150 { 151 std::shared_ptr<ImageReceiverContext> irc = std::make_shared<ImageReceiverContext>(); 152 return irc; 153 } getSurfaceById(std::string id)154 sptr<Surface> ImageReceiver::getSurfaceById(std::string id) 155 { 156 ImageReceiverManager& imageReceiverManager = ImageReceiverManager::getInstance(); 157 sptr<Surface> surface = imageReceiverManager.getSurfaceByKeyId(id); 158 HiLog::Debug(LABEL, "getSurfaceById"); 159 return surface; 160 } CreateImageReceiver(int32_t width,int32_t height,int32_t format,int32_t capicity)161 std::shared_ptr<ImageReceiver> ImageReceiver::CreateImageReceiver(int32_t width, 162 int32_t height, 163 int32_t format, 164 int32_t capicity) 165 { 166 std::shared_ptr<ImageReceiver> iva = std::make_shared<ImageReceiver>(); 167 iva->iraContext_ = ImageReceiverContext::CreateImageReceiverContext(); 168 iva->receiverConsumerSurface_ = Surface::CreateSurfaceAsConsumer(); 169 if (iva->receiverConsumerSurface_ == nullptr) { 170 HiLog::Debug(LABEL, "SurfaceAsConsumer == nullptr"); 171 return iva; 172 } 173 174 iva->receiverConsumerSurface_->SetDefaultWidthAndHeight(width, height); 175 iva->receiverConsumerSurface_->SetQueueSize(capicity); 176 auto p = iva->receiverConsumerSurface_->GetProducer(); 177 iva->receiverProducerSurface_ = Surface::CreateSurfaceAsProducer(p); 178 if (iva->receiverProducerSurface_ == nullptr) { 179 HiLog::Debug(LABEL, "SurfaceAsProducer == nullptr"); 180 return iva; 181 } 182 183 iva->receiverProducerSurface_->SetDefaultWidthAndHeight(width, height); 184 iva->iraContext_->SetReceiverBufferConsumer(iva->receiverConsumerSurface_); 185 iva->iraContext_->SetReceiverBufferProducer(iva->receiverProducerSurface_); 186 iva->iraContext_->SetWidth(width); 187 iva->iraContext_->SetHeight(height); 188 iva->iraContext_->SetFormat(format); 189 iva->iraContext_->SetCapicity(capicity); 190 ImageReceiverManager& imageReceiverManager = ImageReceiverManager::getInstance(); 191 std::string receiverKey = imageReceiverManager.SaveImageReceiver(iva); 192 iva->iraContext_->SetReceiverKey(receiverKey); 193 sptr<ImageReceiverSurfaceListener> listener = new ImageReceiverSurfaceListener(); 194 listener->ir_ = iva; 195 iva->receiverConsumerSurface_-> 196 RegisterConsumerListener((sptr<IBufferConsumerListener> &)listener); 197 return iva; 198 } 199 ReadNextImage()200 OHOS::sptr<OHOS::SurfaceBuffer> ImageReceiver::ReadNextImage() 201 { 202 int32_t flushFence = 0; 203 int64_t timestamp = 0; 204 OHOS::Rect damage = {}; 205 OHOS::sptr<OHOS::SurfaceBuffer> buffer; 206 sptr<Surface> listenerConsumerSurface = iraContext_->GetReceiverBufferConsumer(); 207 SurfaceError surfaceError = listenerConsumerSurface->AcquireBuffer(buffer, flushFence, timestamp, damage); 208 if (surfaceError == SURFACE_ERROR_OK) { 209 iraContext_->currentBuffer_ = buffer; 210 } else { 211 HiLog::Debug(LABEL, "buffer is null"); 212 } 213 return iraContext_->GetCurrentBuffer(); 214 } 215 ReadLastImage()216 OHOS::sptr<OHOS::SurfaceBuffer> ImageReceiver::ReadLastImage() 217 { 218 int32_t flushFence = 0; 219 int64_t timestamp = 0; 220 OHOS::Rect damage = {}; 221 OHOS::sptr<OHOS::SurfaceBuffer> buffer; 222 OHOS::sptr<OHOS::SurfaceBuffer> bufferBefore; 223 sptr<Surface> listenerConsumerSurface = iraContext_->GetReceiverBufferConsumer(); 224 SurfaceError surfaceError = listenerConsumerSurface->AcquireBuffer(buffer, flushFence, timestamp, damage); 225 while (surfaceError == SURFACE_ERROR_OK) { 226 bufferBefore = buffer; 227 surfaceError = listenerConsumerSurface->AcquireBuffer(buffer, flushFence, timestamp, damage); 228 } 229 iraContext_->currentBuffer_ = bufferBefore; 230 return iraContext_->GetCurrentBuffer(); 231 } 232 GetReceiverSurface()233 sptr<Surface> ImageReceiver::GetReceiverSurface() 234 { 235 return iraContext_->GetReceiverBufferProducer(); 236 } 237 ReleaseReceiver()238 void ImageReceiver::ReleaseReceiver() 239 { 240 ImageReceiver::~ImageReceiver(); 241 } 242 } // namespace Media 243 } // namespace OHOS 244