• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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