• 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_creator.h"
17 
18 #include "display/composer/v1_2/display_composer_type.h"
19 #include "image_creator_buffer_processor.h"
20 #include "image_creator_manager.h"
21 #include "image_log.h"
22 #include "image_packer.h"
23 #include "image_source.h"
24 #include "image_utils.h"
25 
26 #undef LOG_DOMAIN
27 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
28 
29 #undef LOG_TAG
30 #define LOG_TAG "imageCreator"
31 
32 namespace OHOS {
33 namespace Media {
34 std::map<uint8_t*, ImageCreator*> ImageCreator::bufferCreatorMap_;
35 std::mutex ImageCreator::creatorMutex_;
~ImageCreator()36 ImageCreator::~ImageCreator()
37 {
38     if (iraContext_ != nullptr) {
39         ImageCreatorManager::ReleaseCreatorById(iraContext_->GetCreatorKey());
40     }
41     creatorConsumerSurface_ = nullptr;
42     creatorProducerSurface_ = nullptr;
43     iraContext_ = nullptr;
44     surfaceBufferReleaseListener_ = nullptr;
45     surfaceBufferAvaliableListener_ = nullptr;
46 }
47 
OnBufferRelease(sptr<SurfaceBuffer> & buffer)48 GSError ImageCreator::OnBufferRelease(sptr<SurfaceBuffer> &buffer)
49 {
50     IMAGE_LOGI("OnBufferRelease");
51     if (buffer == nullptr) {
52         return GSERROR_NO_ENTRY;
53     }
54     std::lock_guard<std::mutex> guard(creatorMutex_);
55     auto iter = bufferCreatorMap_.find(static_cast<uint8_t*>(buffer->GetVirAddr()));
56     if (iter == bufferCreatorMap_.end()) {
57         return GSERROR_NO_ENTRY;
58     }
59     auto icr = iter->second;
60     if (icr->surfaceBufferReleaseListener_ == nullptr) {
61         IMAGE_LOGI("empty icr");
62         return GSERROR_NO_ENTRY;
63     }
64     icr->surfaceBufferReleaseListener_->OnSurfaceBufferRelease();
65     bufferCreatorMap_.erase(iter);
66     return GSERROR_NO_ENTRY;
67 }
68 
CreateImageCreatorContext()69 std::shared_ptr<ImageCreatorContext> ImageCreatorContext ::CreateImageCreatorContext()
70 {
71     std::shared_ptr<ImageCreatorContext> icc = std::make_shared<ImageCreatorContext>();
72     return icc;
73 }
74 
OnBufferAvailable()75 void ImageCreatorSurfaceListener ::OnBufferAvailable()
76 {
77     IMAGE_LOGD("CreatorBufferAvailable");
78     if (ic_->surfaceBufferAvaliableListener_ != nullptr) {
79         ic_->surfaceBufferAvaliableListener_->OnSurfaceBufferAvaliable();
80     }
81 }
82 
CreateImageCreator(int32_t width,int32_t height,int32_t format,int32_t capicity)83 std::shared_ptr<ImageCreator> ImageCreator::CreateImageCreator(int32_t width,
84     int32_t height, int32_t format, int32_t capicity)
85 {
86     std::shared_ptr<ImageCreator> iva = std::make_shared<ImageCreator>();
87     iva->iraContext_ = ImageCreatorContext::CreateImageCreatorContext();
88     iva->creatorConsumerSurface_ = IConsumerSurface::Create();
89     if (iva->creatorConsumerSurface_ == nullptr) {
90         IMAGE_LOGD("SurfaceAsConsumer == nullptr");
91         return iva;
92     }
93     iva->creatorConsumerSurface_->SetDefaultWidthAndHeight(width, height);
94     iva->creatorConsumerSurface_->SetQueueSize(capicity);
95     sptr<ImageCreatorSurfaceListener> listener = new ImageCreatorSurfaceListener();
96     listener->ic_ = iva;
97     iva->creatorConsumerSurface_->
98     RegisterConsumerListener((sptr<IBufferConsumerListener> &)listener);
99     auto p = iva->creatorConsumerSurface_->GetProducer();
100     iva->creatorProducerSurface_ = Surface::CreateSurfaceAsProducer(p);
101     if (iva->creatorProducerSurface_ == nullptr) {
102         IMAGE_LOGD("SurfaceAsProducer == nullptr");
103         return iva;
104     }
105     iva->creatorProducerSurface_->SetQueueSize(capicity);
106     iva->iraContext_->SetCreatorBufferConsumer(iva->creatorConsumerSurface_);
107     iva->iraContext_->SetCreatorBufferProducer(iva->creatorProducerSurface_);
108     iva->iraContext_->SetWidth(width);
109     iva->iraContext_->SetHeight(height);
110     iva->iraContext_->SetFormat(format);
111     iva->iraContext_->SetCapicity(capicity);
112     ImageCreatorManager& imageCreatorManager = ImageCreatorManager::getInstance();
113     std::string creatorKey = imageCreatorManager.SaveImageCreator(iva);
114     iva->iraContext_->SetCreatorKey(creatorKey);
115     iva->creatorProducerSurface_->
116     RegisterReleaseListener(OnBufferRelease);
117     return iva;
118 }
119 
CreatorPackImage(uint8_t * tempBuffer,uint32_t bufferSize,std::unique_ptr<PixelMap> pixelMap)120 int64_t CreatorPackImage(uint8_t *tempBuffer, uint32_t bufferSize, std::unique_ptr<PixelMap> pixelMap)
121 {
122     IMAGE_LOGD("PackImage");
123     ImagePacker imagePacker;
124     PackOption option;
125     option.format = ImageReceiver::OPTION_FORMAT;
126     option.quality = ImageReceiver::OPTION_QUALITY;
127     option.numberHint = static_cast<uint32_t>(ImageReceiver::OPTION_NUMBERHINT);
128     std::set<std::string> formats;
129 
130     uint32_t ret = imagePacker.GetSupportedFormats(formats);
131     if (ret != SUCCESS) {
132         IMAGE_LOGE("image packer get supported format failed, ret=%{public}u.", ret);
133         return 0;
134     } else {
135         IMAGE_LOGD("SUCCESS");
136     }
137     imagePacker.StartPacking(tempBuffer, bufferSize, option);
138     imagePacker.AddImage(*pixelMap);
139     int64_t packedSize = 0;
140     imagePacker.FinalizePacking(packedSize);
141     IMAGE_LOGI("packedSize=%{public}lld.", static_cast<long long>(packedSize));
142     return packedSize;
143 }
144 static const int BIT4 = 4;
145 static const int PRINT_WIDTH = 100;
146 static const int PRINT_WIDTH_MOD = 99;
147 static const uint8_t BIT4_MASK = 0xf;
dumpBuffer(const uint8_t * tempBuffer,int64_t size)148 static void dumpBuffer(const uint8_t* tempBuffer, int64_t size)
149 {
150     std::vector<char> ss;
151     char xx[] = "0123456789ABCDEF";
152     for (int i = 0; i < size; i++) {
153         ss.push_back(xx[(tempBuffer[i]>>BIT4)&BIT4_MASK]);
154         ss.push_back(xx[tempBuffer[i]&BIT4_MASK]);
155         if (i % PRINT_WIDTH == PRINT_WIDTH_MOD) {
156             ss.push_back('\0');
157             IMAGE_LOGI("buffer[%{public}d] = [%{public}s]", i, ss.data());
158             ss.clear();
159             ss.resize(0);
160         }
161     }
162     ss.push_back('\0');
163     IMAGE_LOGI("buffer[LAST] = [%{public}s]", ss.data());
164     ss.clear();
165     ss.resize(0);
166 }
167 
SaveSTP(uint32_t * buffer,uint8_t * tempBuffer,uint32_t bufferSize,InitializationOptions initializationOpts)168 int32_t ImageCreator::SaveSTP(uint32_t *buffer,
169     uint8_t *tempBuffer, uint32_t bufferSize, InitializationOptions initializationOpts)
170 {
171     int64_t errorCode = -1;
172     std::unique_ptr<PixelMap> pixelMap = PixelMap::Create(buffer, bufferSize, initializationOpts);
173     if (pixelMap.get() != nullptr) {
174         ImageInfo imageInfo;
175         pixelMap->GetImageInfo(imageInfo);
176         IMAGE_LOGD("create pixel map imageInfo.size.width=%{public}u.",
177             imageInfo.size.width);
178     } else {
179         IMAGE_LOGE("pixelMap.get() == nullptr");
180         return ERR_MEDIA_INVALID_VALUE;
181     }
182     ImagePacker imagePacker;
183     errorCode = CreatorPackImage(tempBuffer, bufferSize, std::move(pixelMap));
184     if (errorCode > 0) {
185         int64_t len = errorCode < bufferSize ? errorCode : bufferSize;
186         dumpBuffer(tempBuffer, len);
187         errorCode = SUCCESS;
188     } else {
189         errorCode = ERR_MEDIA_INVALID_VALUE;
190     }
191     return errorCode;
192 }
193 
ReleaseBuffer(AllocatorType allocatorType,uint8_t ** buffer)194 static void ReleaseBuffer(AllocatorType allocatorType, uint8_t **buffer)
195 {
196     if (allocatorType == AllocatorType::HEAP_ALLOC) {
197         if (*buffer != nullptr) {
198             free(*buffer);
199             *buffer = nullptr;
200         }
201         return;
202     }
203 }
204 
AllocHeapBuffer(uint64_t bufferSize,uint8_t ** buffer)205 static bool AllocHeapBuffer(uint64_t bufferSize, uint8_t **buffer)
206 {
207     if (bufferSize == 0 || bufferSize > MALLOC_MAX_LENTH) {
208         IMAGE_LOGE("[PostProc]Invalid value of bufferSize");
209         return false;
210     }
211     *buffer = static_cast<uint8_t *>(malloc(bufferSize));
212     if (*buffer == nullptr) {
213         IMAGE_LOGE("[PostProc]alloc covert color buffersize[%{public}llu] failed.",
214             static_cast<unsigned long long>(bufferSize));
215         return false;
216     }
217     errno_t errRet = memset_s(*buffer, bufferSize, 0, bufferSize);
218     if (errRet != EOK) {
219         IMAGE_LOGE("[PostProc]memset convertData fail, errorCode = %{public}d", errRet);
220         ReleaseBuffer(AllocatorType::HEAP_ALLOC, buffer);
221         return false;
222     }
223     return true;
224 }
225 
SaveSenderBufferAsImage(OHOS::sptr<OHOS::SurfaceBuffer> buffer,InitializationOptions initializationOpts)226 int32_t ImageCreator::SaveSenderBufferAsImage(OHOS::sptr<OHOS::SurfaceBuffer> buffer,
227     InitializationOptions initializationOpts)
228 {
229     int32_t errorcode = 0;
230     if (buffer != nullptr) {
231         uint32_t *addr = static_cast<uint32_t *>(buffer->GetVirAddr());
232         uint8_t *addr2 = nullptr;
233         uint32_t size = buffer->GetSize();
234         if (!AllocHeapBuffer(size, &addr2)) {
235             IMAGE_LOGE("AllocHeapBuffer failed");
236             return ERR_MEDIA_INVALID_VALUE;
237         }
238         errorcode = SaveSTP(addr, addr2, size, initializationOpts);
239         ReleaseBuffer(AllocatorType::HEAP_ALLOC, &addr2);
240         (iraContext_->GetCreatorBufferConsumer())->ReleaseBuffer(buffer, -1);
241         IMAGE_LOGI("start release");
242     } else {
243         IMAGE_LOGD("SaveBufferAsImage buffer == nullptr");
244     }
245     return errorcode;
246 }
247 
DequeueImage()248 OHOS::sptr<OHOS::SurfaceBuffer> ImageCreator::DequeueImage()
249 {
250     int32_t flushFence = 0;
251     OHOS::sptr<OHOS::SurfaceBuffer> buffer;
252     sptr<Surface> creatorSurface = iraContext_->GetCreatorBufferProducer();
253     BufferRequestConfig config;
254     config.width = iraContext_->GetWidth();
255     config.height = iraContext_->GetHeight();
256     config.format = OHOS::HDI::Display::Composer::V1_2::PixelFormat::PIXEL_FMT_RGBA_8888;
257     config.strideAlignment = 0x8;
258     config.usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA;
259     config.timeout = 0;
260     SurfaceError surfaceError = creatorSurface->RequestBuffer(buffer, flushFence, config);
261     if (surfaceError == SURFACE_ERROR_OK) {
262         iraContext_->currentCreatorBuffer_ = buffer;
263     } else {
264         IMAGE_LOGD("error : request buffer is null");
265     }
266     if (buffer != nullptr && buffer->GetVirAddr() != nullptr) {
267         std::lock_guard<std::mutex> guard(creatorMutex_);
268         bufferCreatorMap_.insert(
269             std::map<uint8_t*, ImageCreator*>::value_type(static_cast<uint8_t*>(buffer->GetVirAddr()), this));
270     }
271     return iraContext_->currentCreatorBuffer_;
272 }
273 
QueueImage(OHOS::sptr<OHOS::SurfaceBuffer> & buffer)274 void ImageCreator::QueueImage(OHOS::sptr<OHOS::SurfaceBuffer> &buffer)
275 {
276     IMAGE_LOGI("start Queue Image");
277     int32_t flushFence = -1;
278     BufferFlushConfig config;
279     config.damage.w = iraContext_->GetWidth();
280     config.damage.h = iraContext_->GetHeight();
281     sptr<Surface> creatorSurface = iraContext_->GetCreatorBufferProducer();
282     SurfaceError surfaceError = creatorSurface->FlushBuffer(buffer, flushFence, config);
283     IMAGE_LOGI("finish Queue Image");
284     if (surfaceError != SURFACE_ERROR_OK) {
285         IMAGE_LOGD("Queue fail");
286     }
287 }
GetCreatorSurface()288 sptr<IConsumerSurface> ImageCreator::GetCreatorSurface()
289 {
290     return iraContext_->GetCreatorBufferConsumer();
291 }
292 
getSurfaceById(std::string id)293 sptr<IConsumerSurface> ImageCreator::getSurfaceById(std::string id)
294 {
295     ImageCreatorManager& imageCreatorManager = ImageCreatorManager::getInstance();
296     sptr<IConsumerSurface> surface = imageCreatorManager.GetSurfaceByKeyId(id);
297     IMAGE_LOGD("getSurfaceByCreatorId");
298     return surface;
299 }
ReleaseCreator()300 void ImageCreator::ReleaseCreator()
301 {
302     ImageCreator::~ImageCreator();
303 }
304 
GetBufferProcessor()305 std::shared_ptr<IBufferProcessor> ImageCreator::GetBufferProcessor()
306 {
307     if (bufferProcessor_ == nullptr) {
308         bufferProcessor_ = std::make_shared<ImageCreatorBufferProcessor>(this);
309     }
310     return bufferProcessor_;
311 }
DequeueNativeImage()312 std::shared_ptr<NativeImage> ImageCreator::DequeueNativeImage()
313 {
314     if (GetBufferProcessor() == nullptr) {
315         return nullptr;
316     }
317 
318     auto surfaceBuffer = DequeueImage();
319     if (surfaceBuffer == nullptr) {
320         return nullptr;
321     }
322     return std::make_shared<NativeImage>(surfaceBuffer, GetBufferProcessor());
323 }
QueueNativeImage(std::shared_ptr<NativeImage> image)324 void ImageCreator::QueueNativeImage(std::shared_ptr<NativeImage> image)
325 {
326     if (image == nullptr || image->GetBuffer() == nullptr) {
327         return;
328     }
329     auto buffer = image->GetBuffer();
330     QueueImage(buffer);
331 }
332 } // namespace Media
333 } // namespace OHOS
334