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
18 #include "image_log.h"
19 #include "image_packer.h"
20 #include "image_source.h"
21 #include "image_utils.h"
22 #include "image_receiver_buffer_processor.h"
23 #include "image_receiver_manager.h"
24
25 #undef LOG_DOMAIN
26 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
27
28 #undef LOG_TAG
29 #define LOG_TAG "imageReceiver"
30
31 namespace OHOS {
32 namespace Media {
~ImageReceiver()33 ImageReceiver::~ImageReceiver()
34 {
35 std::lock_guard<std::mutex> guard(imageReceiverMutex_);
36 if (receiverConsumerSurface_ != nullptr) {
37 receiverConsumerSurface_->UnregisterConsumerListener();
38 }
39 receiverConsumerSurface_ = nullptr;
40 receiverProducerSurface_ = nullptr;
41 iraContext_ = nullptr;
42 surfaceBufferAvaliableListener_ = nullptr;
43 bufferProcessor_ = nullptr;
44 }
45
46 enum class Mode {
47 MODE_PREVIEW = 0,
48 MODE_PHOTO
49 };
50
PackImage(int & fd,std::unique_ptr<PixelMap> pixelMap)51 int64_t PackImage(int &fd, std::unique_ptr<PixelMap> pixelMap)
52 {
53 IMAGE_LOGD("PackImage");
54 ImagePacker imagePacker;
55 PackOption option;
56 option.format = ImageReceiver::OPTION_FORMAT;
57 option.quality = ImageReceiver::OPTION_QUALITY;
58 option.numberHint = ImageReceiver::OPTION_NUMBERHINT;
59 std::set<std::string> formats;
60 if (pixelMap == nullptr) {
61 IMAGE_LOGE("pixelMap is nullptr");
62 return 0;
63 }
64 uint32_t ret = imagePacker.GetSupportedFormats(formats);
65 if (ret != SUCCESS) {
66 IMAGE_LOGE("image packer get supported format failed, ret=%{public}u.", ret);
67 return 0;
68 } else {
69 IMAGE_LOGD("SUCCESS");
70 }
71 imagePacker.StartPacking(fd, option);
72 imagePacker.AddImage(*pixelMap);
73 int64_t packedSize = 0;
74 imagePacker.FinalizePacking(packedSize);
75 IMAGE_LOGD("packedSize=%{public}lld.", static_cast<long long>(packedSize));
76 IMAGE_LOGD("packedSize=%{public}lld.", static_cast<long long>(packedSize));
77 return packedSize;
78 }
79
getSurfacePixelMap(InitializationOptions initializationOpts)80 std::unique_ptr<PixelMap> ImageReceiver::getSurfacePixelMap(InitializationOptions initializationOpts)
81 {
82 uint32_t *addr = reinterpret_cast<uint32_t *>(iraContext_->currentBuffer_->GetVirAddr());
83 int32_t size = iraContext_->currentBuffer_->GetSize();
84 return PixelMap::Create(addr, (uint32_t)size, initializationOpts);
85 }
86
SaveSTP(uint32_t * buffer,uint32_t bufferSize,int & fd,InitializationOptions initializationOpts)87 static int32_t SaveSTP(uint32_t *buffer,
88 uint32_t bufferSize,
89 int &fd,
90 InitializationOptions initializationOpts)
91 {
92 int64_t errorCode = -1;
93 std::unique_ptr<PixelMap> pixelMap = PixelMap::Create(buffer, bufferSize, initializationOpts);
94 if (pixelMap.get() != nullptr) {
95 ImageInfo imageInfo;
96 pixelMap->GetImageInfo(imageInfo);
97 IMAGE_LOGD("create pixel map imageInfo.size.width=%{public}u.", imageInfo.size.width);
98 } else {
99 IMAGE_LOGE("pixelMap.get() == nullptr");
100 return ERR_MEDIA_INVALID_VALUE;
101 }
102 ImagePacker imagePacker;
103 errorCode = PackImage(fd, std::move(pixelMap));
104 if (errorCode > 0) {
105 errorCode = SUCCESS;
106 } else {
107 errorCode = ERR_MEDIA_INVALID_VALUE;
108 }
109 return errorCode;
110 }
111
SaveBufferAsImage(int & fd,OHOS::sptr<OHOS::SurfaceBuffer> buffer,InitializationOptions initializationOpts)112 int32_t ImageReceiver::SaveBufferAsImage(int &fd,
113 OHOS::sptr<OHOS::SurfaceBuffer> buffer,
114 InitializationOptions initializationOpts)
115 {
116 int32_t errorcode = 0;
117 if (buffer != nullptr) {
118 uint32_t *addr = reinterpret_cast<uint32_t *>(buffer->GetVirAddr());
119 int32_t size = buffer->GetSize();
120 errorcode = SaveSTP(addr, static_cast<uint32_t>(size), fd, initializationOpts);
121 if ((iraContext_->GetReceiverBufferConsumer()) != nullptr) {
122 (iraContext_->GetReceiverBufferConsumer())->ReleaseBuffer(buffer, -1);
123 } else {
124 IMAGE_LOGD("iraContext_->GetReceiverBufferConsumer() == nullptr");
125 }
126 } else {
127 IMAGE_LOGD("SaveBufferAsImage buffer == nullptr");
128 }
129 return errorcode;
130 }
131
SaveBufferAsImage(int & fd,InitializationOptions initializationOpts)132 int32_t ImageReceiver::SaveBufferAsImage(int &fd,
133 InitializationOptions initializationOpts)
134 {
135 if (iraContext_->currentBuffer_ != nullptr) {
136 return SaveBufferAsImage(fd, iraContext_->currentBuffer_, initializationOpts);
137 }
138 IMAGE_LOGD("iraContext_->GetCurrentBuffer() == nullptr");
139 return 0;
140 }
141
ReleaseBuffer(OHOS::sptr<OHOS::SurfaceBuffer> & buffer)142 void ImageReceiver::ReleaseBuffer(OHOS::sptr<OHOS::SurfaceBuffer> &buffer) __attribute__((no_sanitize("cfi")))
143 {
144 std::lock_guard<std::mutex> guard(imageReceiverMutex_);
145 if (buffer != nullptr) {
146 if (iraContext_ != nullptr) {
147 auto listenerConsumerSurface = iraContext_->GetReceiverBufferConsumer();
148 if (listenerConsumerSurface != nullptr) {
149 listenerConsumerSurface->ReleaseBuffer(buffer, -1);
150 } else {
151 IMAGE_LOGD("listenerConsumerSurface == nullptr");
152 }
153 } else {
154 IMAGE_LOGD("iraContext_ == nullptr");
155 }
156 buffer = nullptr;
157 }
158 }
159
OnBufferAvailable()160 void ImageReceiverSurfaceListener ::OnBufferAvailable()
161 {
162 IMAGE_LOGD("OnBufferAvailable");
163 auto ir = ir_.lock();
164 if (ir && ir->surfaceBufferAvaliableListener_ != nullptr) {
165 ir->surfaceBufferAvaliableListener_->OnSurfaceBufferAvaliable();
166 }
167 }
168
CreateImageReceiverContext()169 std::shared_ptr<ImageReceiverContext> ImageReceiverContext ::CreateImageReceiverContext()
170 {
171 std::shared_ptr<ImageReceiverContext> irc = std::make_shared<ImageReceiverContext>();
172 return irc;
173 }
174
getSurfaceById(std::string id)175 sptr<Surface> ImageReceiver::getSurfaceById(std::string id)
176 {
177 ImageReceiverManager& imageReceiverManager = ImageReceiverManager::getInstance();
178 sptr<Surface> surface = imageReceiverManager.getSurfaceByKeyId(id);
179 IMAGE_LOGD("getSurfaceById");
180 return surface;
181 }
182
CreateImageReceiver(int32_t width,int32_t height,int32_t format,int32_t capicity)183 std::shared_ptr<ImageReceiver> ImageReceiver::CreateImageReceiver(int32_t width,
184 int32_t height,
185 int32_t format,
186 int32_t capicity)
187 {
188 std::shared_ptr<ImageReceiver> iva = std::make_shared<ImageReceiver>();
189 iva->iraContext_ = ImageReceiverContext::CreateImageReceiverContext();
190 iva->receiverConsumerSurface_ = IConsumerSurface::Create();
191 if (iva->receiverConsumerSurface_ == nullptr) {
192 IMAGE_LOGD("SurfaceAsConsumer == nullptr");
193 return iva;
194 }
195
196 iva->receiverConsumerSurface_->SetDefaultWidthAndHeight(width, height);
197 iva->receiverConsumerSurface_->SetQueueSize(capicity);
198 iva->receiverConsumerSurface_->SetDefaultUsage(BUFFER_USAGE_CPU_READ);
199
200 auto p = iva->receiverConsumerSurface_->GetProducer();
201 iva->receiverProducerSurface_ = Surface::CreateSurfaceAsProducer(p);
202 if (iva->receiverProducerSurface_ == nullptr) {
203 IMAGE_LOGD("SurfaceAsProducer == nullptr");
204 return iva;
205 }
206
207 iva->iraContext_->SetReceiverBufferConsumer(iva->receiverConsumerSurface_);
208 iva->iraContext_->SetReceiverBufferProducer(iva->receiverProducerSurface_);
209 iva->iraContext_->SetWidth(width);
210 iva->iraContext_->SetHeight(height);
211 iva->iraContext_->SetFormat(format);
212 iva->iraContext_->SetCapicity(capicity);
213 ImageReceiverManager& imageReceiverManager = ImageReceiverManager::getInstance();
214 std::string receiverKey = imageReceiverManager.SaveImageReceiver(iva);
215 iva->iraContext_->SetReceiverKey(receiverKey);
216 sptr<ImageReceiverSurfaceListener> listener = new ImageReceiverSurfaceListener();
217 listener->ir_ = iva;
218 iva->receiverConsumerSurface_->
219 RegisterConsumerListener((sptr<IBufferConsumerListener> &)listener);
220 return iva;
221 }
222
ReadNextImage(int64_t & timestamp)223 OHOS::sptr<OHOS::SurfaceBuffer> ImageReceiver::ReadNextImage(int64_t ×tamp)
224 {
225 int32_t flushFence = 0;
226 OHOS::Rect damage = {};
227 OHOS::sptr<OHOS::SurfaceBuffer> buffer;
228 sptr<IConsumerSurface> listenerConsumerSurface = iraContext_->GetReceiverBufferConsumer();
229 SurfaceError surfaceError = listenerConsumerSurface->AcquireBuffer(buffer, flushFence, timestamp, damage);
230 if (surfaceError == SURFACE_ERROR_OK) {
231 iraContext_->currentBuffer_ = buffer;
232 } else {
233 IMAGE_LOGD("buffer is null");
234 }
235 IMAGE_LOGD("[ImageReceiver] ReadNextImage %{public}lld", static_cast<long long>(timestamp));
236 return iraContext_->GetCurrentBuffer();
237 }
238
ReadNextImage()239 OHOS::sptr<OHOS::SurfaceBuffer> ImageReceiver::ReadNextImage()
240 {
241 int32_t flushFence = 0;
242 int64_t timestamp = 0;
243 OHOS::Rect damage = {};
244 OHOS::sptr<OHOS::SurfaceBuffer> buffer;
245 sptr<IConsumerSurface> listenerConsumerSurface = iraContext_->GetReceiverBufferConsumer();
246 SurfaceError surfaceError = listenerConsumerSurface->AcquireBuffer(buffer, flushFence, timestamp, damage);
247 if (surfaceError == SURFACE_ERROR_OK) {
248 iraContext_->currentBuffer_ = buffer;
249 } else {
250 IMAGE_LOGD("buffer is null");
251 }
252 IMAGE_LOGD("[ImageReceiver] ReadNextImage %{public}lld", static_cast<long long>(timestamp));
253 return iraContext_->GetCurrentBuffer();
254 }
255
ReadLastImage(int64_t & timestamp)256 OHOS::sptr<OHOS::SurfaceBuffer> ImageReceiver::ReadLastImage(int64_t ×tamp)
257 {
258 int32_t flushFence = 0;
259 OHOS::Rect damage = {};
260 OHOS::sptr<OHOS::SurfaceBuffer> buffer;
261 OHOS::sptr<OHOS::SurfaceBuffer> bufferBefore;
262 sptr<IConsumerSurface> listenerConsumerSurface = iraContext_->GetReceiverBufferConsumer();
263 SurfaceError surfaceError = listenerConsumerSurface->AcquireBuffer(buffer, flushFence, timestamp, damage);
264 while (surfaceError == SURFACE_ERROR_OK) {
265 bufferBefore = buffer;
266 surfaceError = listenerConsumerSurface->AcquireBuffer(buffer, flushFence, timestamp, damage);
267 }
268
269 iraContext_->currentBuffer_ = bufferBefore;
270 IMAGE_LOGD("[ImageReceiver] ReadLastImage %{public}lld", static_cast<long long>(timestamp));
271 return iraContext_->GetCurrentBuffer();
272 }
273
ReadLastImage()274 OHOS::sptr<OHOS::SurfaceBuffer> ImageReceiver::ReadLastImage()
275 {
276 int32_t flushFence = 0;
277 int64_t timestamp = 0;
278 OHOS::Rect damage = {};
279 OHOS::sptr<OHOS::SurfaceBuffer> buffer;
280 OHOS::sptr<OHOS::SurfaceBuffer> bufferBefore;
281 sptr<IConsumerSurface> listenerConsumerSurface = iraContext_->GetReceiverBufferConsumer();
282 SurfaceError surfaceError = listenerConsumerSurface->AcquireBuffer(buffer, flushFence, timestamp, damage);
283 while (surfaceError == SURFACE_ERROR_OK) {
284 bufferBefore = buffer;
285 surfaceError = listenerConsumerSurface->AcquireBuffer(buffer, flushFence, timestamp, damage);
286 }
287
288 iraContext_->currentBuffer_ = bufferBefore;
289 IMAGE_LOGD("[ImageReceiver] ReadLastImage %{public}lld", static_cast<long long>(timestamp));
290 return iraContext_->GetCurrentBuffer();
291 }
292
GetReceiverSurface()293 sptr<Surface> ImageReceiver::GetReceiverSurface()
294 {
295 if (iraContext_ != nullptr) {
296 return iraContext_->GetReceiverBufferProducer();
297 }
298 return nullptr;
299 }
300
ReleaseReceiver()301 void ImageReceiver::ReleaseReceiver()
302 {
303 ImageReceiver::~ImageReceiver();
304 }
305
GetBufferProcessor()306 std::shared_ptr<IBufferProcessor> ImageReceiver::GetBufferProcessor()
307 {
308 if (bufferProcessor_ == nullptr) {
309 bufferProcessor_ = std::make_shared<ImageReceiverBufferProcessor>(this);
310 }
311 return bufferProcessor_;
312 }
313
NextNativeImage()314 std::shared_ptr<NativeImage> ImageReceiver::NextNativeImage()
315 {
316 if (GetBufferProcessor() == nullptr) {
317 return nullptr;
318 }
319 int64_t timestamp = 0;
320 auto surfaceBuffer = ReadNextImage(timestamp);
321 if (surfaceBuffer == nullptr) {
322 return nullptr;
323 }
324 return std::make_shared<NativeImage>(surfaceBuffer, GetBufferProcessor(), timestamp);
325 }
326
LastNativeImage()327 std::shared_ptr<NativeImage> ImageReceiver::LastNativeImage()
328 {
329 if (GetBufferProcessor() == nullptr) {
330 return nullptr;
331 }
332 int64_t timestamp = 0;
333 auto surfaceBuffer = ReadLastImage(timestamp);
334 if (surfaceBuffer == nullptr) {
335 return nullptr;
336 }
337 return std::make_shared<NativeImage>(surfaceBuffer, GetBufferProcessor(), timestamp);
338 }
339 } // namespace Media
340 } // namespace OHOS
341