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