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