1 /*
2  * Copyright (c) 2022-2024 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 "scale_convert_process.h"
17 
18 #include "distributed_camera_constants.h"
19 #include "distributed_camera_errno.h"
20 #include "distributed_hardware_log.h"
21 #include "dcamera_frame_info.h"
22 
23 namespace OHOS {
24 namespace DistributedHardware {
~ScaleConvertProcess()25 ScaleConvertProcess::~ScaleConvertProcess()
26 {
27     DumpFileUtil::CloseDumpFile(&dumpFile_);
28     if (isScaleConvert_.load()) {
29         DHLOGI("~ScaleConvertProcess : ReleaseProcessNode");
30         ReleaseProcessNode();
31     }
32 }
33 
InitNode(const VideoConfigParams & sourceConfig,const VideoConfigParams & targetConfig,VideoConfigParams & processedConfig)34 int32_t ScaleConvertProcess::InitNode(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig,
35     VideoConfigParams& processedConfig)
36 {
37     DHLOGI("ScaleConvertProcess : InitNode.");
38     sourceConfig_ = sourceConfig;
39     targetConfig_ = targetConfig;
40     processedConfig_ = sourceConfig;
41     processedConfig_.SetWidthAndHeight(targetConfig.GetWidth(), targetConfig.GetHeight());
42     processedConfig_.SetVideoformat(targetConfig.GetVideoformat());
43     processedConfig = processedConfig_;
44 
45     if (!IsConvertible(sourceConfig, targetConfig)) {
46         DHLOGI("sourceConfig: Videoformat %{public}d Width %{public}d, Height %{public}d is the same as the "
47             "targetConfig: Videoformat %{public}d Width %{public}d, Height %{public}d.",
48             sourceConfig.GetVideoformat(), sourceConfig.GetWidth(), sourceConfig.GetHeight(),
49             targetConfig.GetVideoformat(), targetConfig.GetWidth(), targetConfig.GetHeight());
50     }
51 
52     isScaleConvert_.store(true);
53     return DCAMERA_OK;
54 }
55 
IsConvertible(const VideoConfigParams & sourceConfig,const VideoConfigParams & targetConfig)56 bool ScaleConvertProcess::IsConvertible(const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig)
57 {
58     return (sourceConfig_.GetWidth() != targetConfig.GetWidth()) ||
59         (sourceConfig_.GetHeight() != targetConfig.GetHeight()) ||
60         (sourceConfig_.GetVideoformat() != targetConfig.GetVideoformat());
61 }
62 
ReleaseProcessNode()63 void ScaleConvertProcess::ReleaseProcessNode()
64 {
65     DHLOGI("Start release [%{public}zu] node : ScaleConvertNode.", nodeRank_);
66     isScaleConvert_.store(false);
67 
68     if (nextDataProcess_ != nullptr) {
69         nextDataProcess_->ReleaseProcessNode();
70         nextDataProcess_ = nullptr;
71     }
72     DHLOGI("Release [%{public}zu] node : ScaleConvertNode end.", nodeRank_);
73 }
74 
ProcessData(std::vector<std::shared_ptr<DataBuffer>> & inputBuffers)75 int ScaleConvertProcess::ProcessData(std::vector<std::shared_ptr<DataBuffer>>& inputBuffers)
76 {
77     int64_t startScaleTime = GetNowTimeStampUs();
78     DHLOGD("Process data in ScaleConvertProcess.");
79     if (!isScaleConvert_.load()) {
80         DHLOGE("Scale Convert node occurred error or start release.");
81         return DCAMERA_DISABLE_PROCESS;
82     }
83 
84     if (inputBuffers.empty() || inputBuffers[0] == nullptr) {
85         DHLOGE("The input data buffers is empty.");
86         return DCAMERA_BAD_VALUE;
87     }
88     inputBuffers[0]->frameInfo_.timePonit.startScale = startScaleTime;
89     DumpFileUtil::OpenDumpFile(DUMP_SERVER_PARA, DUMP_DCAMERA_AFTER_SCALE_FILENAME, &dumpFile_);
90 
91     if (!IsConvertible(sourceConfig_, processedConfig_)) {
92         DHLOGD("The target resolution: %{public}dx%{public}d format: %{public}d is the same as the source "
93             "resolution: %{public}dx%{public}d format: %{public}d",
94             processedConfig_.GetWidth(), processedConfig_.GetHeight(), processedConfig_.GetVideoformat(),
95             sourceConfig_.GetWidth(), sourceConfig_.GetHeight(), sourceConfig_.GetVideoformat());
96         return ConvertDone(inputBuffers);
97     }
98 
99     ImageUnitInfo srcImgInfo {Videoformat::YUVI420, 0, 0, 0, 0, 0, 0, nullptr};
100     if ((GetImageUnitInfo(srcImgInfo, inputBuffers[0]) != DCAMERA_OK) || !CheckScaleProcessInputInfo(srcImgInfo)) {
101         DHLOGE("ScaleConvertProcess : srcImgInfo error.");
102         return DCAMERA_BAD_VALUE;
103     }
104 
105     size_t dstBuffSize = 0;
106     CalculateBuffSize(dstBuffSize);
107     std::shared_ptr<DataBuffer> dstBuf = std::make_shared<DataBuffer>(dstBuffSize);
108     ImageUnitInfo dstImgInfo = { processedConfig_.GetVideoformat(), processedConfig_.GetWidth(),
109         processedConfig_.GetHeight(), processedConfig_.GetWidth(), processedConfig_.GetHeight(),
110         processedConfig_.GetWidth() * processedConfig_.GetHeight(), dstBuf->Size(), dstBuf };
111     if (ScaleConvert(srcImgInfo, dstImgInfo) != DCAMERA_OK) {
112         DHLOGE("ScaleConvertProcess : Scale convert failed.");
113         return DCAMERA_BAD_OPERATE;
114     }
115 
116     dstBuf->frameInfo_ = inputBuffers[0]->frameInfo_;
117     dstBuf->SetInt32("Videoformat", static_cast<int32_t>(processedConfig_.GetVideoformat()));
118     dstBuf->SetInt32("alignedWidth", processedConfig_.GetWidth());
119     dstBuf->SetInt32("alignedHeight", processedConfig_.GetHeight());
120     dstBuf->SetInt32("width", processedConfig_.GetWidth());
121     dstBuf->SetInt32("height", processedConfig_.GetHeight());
122 
123     DumpFileUtil::WriteDumpFile(dumpFile_, static_cast<void *>(dstBuf->Data()), dstBuf->Size());
124     std::vector<std::shared_ptr<DataBuffer>> outputBuffers;
125     outputBuffers.push_back(dstBuf);
126     return ConvertDone(outputBuffers);
127 }
128 
CalculateBuffSize(size_t & dstBuffSize)129 void ScaleConvertProcess::CalculateBuffSize(size_t& dstBuffSize)
130 {
131     if (processedConfig_.GetVideoformat() == Videoformat::RGBA_8888) {
132         dstBuffSize = static_cast<size_t>(processedConfig_.GetWidth() * processedConfig_.GetHeight() *
133             RGB32_MEMORY_COEFFICIENT);
134     } else {
135         dstBuffSize = static_cast<size_t>(
136             processedConfig_.GetWidth() * processedConfig_.GetHeight() * YUV_BYTES_PER_PIXEL / Y2UV_RATIO);
137     }
138 }
139 
GetImageUnitInfo(ImageUnitInfo & imgInfo,const std::shared_ptr<DataBuffer> & imgBuf)140 int32_t ScaleConvertProcess::GetImageUnitInfo(ImageUnitInfo& imgInfo, const std::shared_ptr<DataBuffer>& imgBuf)
141 {
142     if (imgBuf == nullptr) {
143         DHLOGE("GetImageUnitInfo failed, imgBuf is nullptr.");
144         return DCAMERA_BAD_VALUE;
145     }
146 
147     bool findErr = true;
148     int32_t colorFormat = 0;
149     findErr = findErr && imgBuf->FindInt32("Videoformat", colorFormat);
150     if (!findErr) {
151         DHLOGE("GetImageUnitInfo failed, Videoformat is null.");
152         return DCAMERA_NOT_FOUND;
153     }
154     if (colorFormat != static_cast<int32_t>(Videoformat::YUVI420) &&
155         colorFormat != static_cast<int32_t>(Videoformat::NV12) &&
156         colorFormat != static_cast<int32_t>(Videoformat::NV21)) {
157         DHLOGE("GetImageUnitInfo failed, colorFormat %{public}d are not supported.", colorFormat);
158         return DCAMERA_NOT_FOUND;
159     }
160     imgInfo.colorFormat = static_cast<Videoformat>(colorFormat);
161     findErr = findErr && imgBuf->FindInt32("width", imgInfo.width);
162     findErr = findErr && imgBuf->FindInt32("height", imgInfo.height);
163     findErr = findErr && imgBuf->FindInt32("alignedWidth", imgInfo.alignedWidth);
164     findErr = findErr && imgBuf->FindInt32("alignedHeight", imgInfo.alignedHeight);
165     if (!findErr) {
166         DHLOGE("GetImageUnitInfo failed, width %{public}d, height %{public}d, alignedWidth %{public}d, "
167             "alignedHeight %{public}d.", imgInfo.width, imgInfo.height, imgInfo.alignedWidth, imgInfo.alignedHeight);
168         return DCAMERA_NOT_FOUND;
169     }
170 
171     imgInfo.chromaOffset = static_cast<size_t>(imgInfo.alignedWidth * imgInfo.alignedHeight);
172     imgInfo.imgSize = imgBuf->Size();
173     imgInfo.imgData = imgBuf;
174 
175     DHLOGD("ScaleConvertProcess imgBuf info : Videoformat %{public}d, alignedWidth %{public}d, alignedHeight "
176         "%{public}d, width %{public}d, height %{public}d, chromaOffset %{public}zu, imgSize %{public}zu.",
177         imgInfo.colorFormat, imgInfo.alignedWidth, imgInfo.alignedHeight,
178         imgInfo.width, imgInfo.height, imgInfo.chromaOffset, imgInfo.imgSize);
179     return DCAMERA_OK;
180 }
181 
CheckScaleProcessInputInfo(const ImageUnitInfo & srcImgInfo)182 bool ScaleConvertProcess::CheckScaleProcessInputInfo(const ImageUnitInfo& srcImgInfo)
183 {
184     return srcImgInfo.colorFormat == Videoformat::YUVI420 &&
185         srcImgInfo.width == sourceConfig_.GetWidth() &&
186         srcImgInfo.height == sourceConfig_.GetHeight() &&
187         IsCorrectImageUnitInfo(srcImgInfo);
188 }
189 
CheckScaleConvertInfo(const ImageUnitInfo & srcImgInfo,const ImageUnitInfo & dstImgInfo)190 bool ScaleConvertProcess::CheckScaleConvertInfo(const ImageUnitInfo& srcImgInfo, const ImageUnitInfo& dstImgInfo)
191 {
192     if (srcImgInfo.imgData == nullptr || dstImgInfo.imgData == nullptr) {
193         DHLOGE("The imgData of srcImgInfo or the imgData of dstImgInfo are null!");
194         return false;
195     }
196 
197     if (!IsCorrectImageUnitInfo(srcImgInfo)) {
198         DHLOGE("srcImginfo fail: width %{public}d, height %{public}d, alignedWidth %{public}d, alignedHeight "
199             "%{public}d, chromaOffset %{public}zu, imgSize %{public}zu.", srcImgInfo.width, srcImgInfo.height,
200             srcImgInfo.alignedWidth, srcImgInfo.alignedHeight, srcImgInfo.chromaOffset, srcImgInfo.imgSize);
201         return false;
202     }
203 
204     if (!IsCorrectImageUnitInfo(dstImgInfo)) {
205         DHLOGE("dstImginfo fail: width %{public}d, height %{public}d, alignedWidth %{public}d, alignedHeight "
206             "%{public}d, chromaOffset %{public}zu, imgSize %{public}zu.", dstImgInfo.width, dstImgInfo.height,
207             dstImgInfo.alignedWidth, dstImgInfo.alignedHeight, dstImgInfo.chromaOffset, dstImgInfo.imgSize);
208         return false;
209     }
210 
211     if ((dstImgInfo.width == srcImgInfo.alignedWidth) && (dstImgInfo.height == srcImgInfo.alignedHeight) &&
212         (dstImgInfo.colorFormat == srcImgInfo.colorFormat)) {
213         DHLOGE("Comparison ImgInfo fail: dstwidth %{public}d, dstheight %{public}d, dstColorFormat %{public}d, "
214             "srcAlignedWidth %{public}d, srcAlignedHeight %{public}d, srcColorFormat %{public}d.",
215             dstImgInfo.width, dstImgInfo.height, dstImgInfo.colorFormat,
216             srcImgInfo.alignedWidth, srcImgInfo.alignedHeight, srcImgInfo.colorFormat);
217         return false;
218     }
219 
220     return true;
221 }
222 
IsCorrectImageUnitInfo(const ImageUnitInfo & imgInfo)223 bool ScaleConvertProcess::IsCorrectImageUnitInfo(const ImageUnitInfo& imgInfo)
224 {
225     size_t expectedImgSize = static_cast<size_t>(imgInfo.alignedWidth * imgInfo.alignedHeight *
226         YUV_BYTES_PER_PIXEL / Y2UV_RATIO);
227     size_t expectedChromaOffset = static_cast<size_t>(imgInfo.alignedWidth * imgInfo.alignedHeight);
228     return (imgInfo.width <= imgInfo.alignedWidth && imgInfo.height <= imgInfo.alignedHeight &&
229         imgInfo.imgSize >= expectedImgSize && imgInfo.chromaOffset == expectedChromaOffset);
230 }
231 
ScaleConvert(ImageUnitInfo & srcImgInfo,ImageUnitInfo & dstImgInfo)232 int32_t ScaleConvertProcess::ScaleConvert(ImageUnitInfo& srcImgInfo, ImageUnitInfo& dstImgInfo)
233 {
234     DHLOGD("Scale convert start.");
235     if (!CheckScaleConvertInfo(srcImgInfo, dstImgInfo)) {
236         DHLOGE("CheckScaleConvertInfo failed.");
237         return DCAMERA_BAD_VALUE;
238     }
239 
240     std::shared_ptr<DataBuffer> dstBuf =
241         std::make_shared<DataBuffer>(dstImgInfo.width * dstImgInfo.height * YUV_BYTES_PER_PIXEL / Y2UV_RATIO);
242     int32_t ret = ConvertResolution(srcImgInfo, dstImgInfo, dstBuf);
243     if (ret != DCAMERA_OK) {
244         DHLOGE("Convert I420 scale failed.");
245         return ret;
246     }
247 
248     if (processedConfig_.GetVideoformat() == Videoformat::NV21) {
249         ret = ConvertFormatToNV21(srcImgInfo, dstImgInfo, dstBuf);
250     } else if (processedConfig_.GetVideoformat() == Videoformat::RGBA_8888) {
251         ret = ConvertFormatToRGBA(srcImgInfo, dstImgInfo, dstBuf);
252     }
253     if (ret != DCAMERA_OK) {
254         DHLOGE("Convert I420 to format: %{public}d failed.", processedConfig_.GetVideoformat());
255         return ret;
256     }
257 
258     DHLOGD("Scale convert end.");
259     return DCAMERA_OK;
260 }
261 
ConvertResolution(ImageUnitInfo & srcImgInfo,ImageUnitInfo & dstImgInfo,std::shared_ptr<DataBuffer> & dstBuf)262 int32_t ScaleConvertProcess::ConvertResolution(ImageUnitInfo& srcImgInfo, ImageUnitInfo& dstImgInfo,
263     std::shared_ptr<DataBuffer>& dstBuf)
264 {
265     if ((srcImgInfo.width == dstImgInfo.width) && (srcImgInfo.height == dstImgInfo.height)) {
266         dstBuf = srcImgInfo.imgData;
267         DHLOGD("Convert I420 Scale: srcImgInfo is the same as dstImgInfo");
268         return DCAMERA_OK;
269     }
270     CHECK_AND_RETURN_RET_LOG((srcImgInfo.imgData == nullptr), DCAMERA_BAD_VALUE, "Data buffer exists null data");
271     DHLOGD("Convert I420 Scale: format=%{public}d, width=[%{public}d, %{public}d], height=[%{public}d, %{public}d]",
272         srcImgInfo.colorFormat, srcImgInfo.width, srcImgInfo.alignedWidth, srcImgInfo.height, srcImgInfo.alignedHeight);
273     int srcSizeY = srcImgInfo.width * srcImgInfo.height;
274     int srcSizeUV = (static_cast<uint32_t>(srcImgInfo.width) >> MEMORY_RATIO_UV) *
275                     (static_cast<uint32_t>(srcImgInfo.height) >> MEMORY_RATIO_UV);
276     uint8_t *srcDataY = srcImgInfo.imgData->Data();
277     uint8_t *srcDataU = srcImgInfo.imgData->Data() + srcSizeY;
278     uint8_t *srcDataV = srcImgInfo.imgData->Data() + srcSizeY + srcSizeUV;
279 
280     int dstSizeY = dstImgInfo.width * dstImgInfo.height;
281     int dstSizeUV = (static_cast<uint32_t>(dstImgInfo.width) >> MEMORY_RATIO_UV) *
282                     (static_cast<uint32_t>(dstImgInfo.height) >> MEMORY_RATIO_UV);
283     uint8_t *dstDataY = dstBuf->Data();
284     uint8_t *dstDataU = dstBuf->Data() + dstSizeY;
285     uint8_t *dstDataV = dstBuf->Data() + dstSizeY + dstSizeUV;
286 
287     auto converter = ConverterHandle::GetInstance().GetHandle();
288     CHECK_AND_RETURN_RET_LOG(converter.I420Scale == nullptr, DCAMERA_BAD_VALUE, "converter is invalid.");
289     int32_t ret = converter.I420Scale(
290         srcDataY, srcImgInfo.width,
291         srcDataU, static_cast<uint32_t>(srcImgInfo.width) >> MEMORY_RATIO_UV,
292         srcDataV, static_cast<uint32_t>(srcImgInfo.width) >> MEMORY_RATIO_UV,
293         srcImgInfo.width, srcImgInfo.height,
294         dstDataY, dstImgInfo.width,
295         dstDataU, static_cast<uint32_t>(dstImgInfo.width) >> MEMORY_RATIO_UV,
296         dstDataV, static_cast<uint32_t>(dstImgInfo.width) >> MEMORY_RATIO_UV,
297         dstImgInfo.width, dstImgInfo.height,
298         OpenSourceLibyuv::FilterMode::kFilterNone);
299     if (ret != DCAMERA_OK) {
300         DHLOGE("Convert I420 scale failed.");
301         return DCAMERA_BAD_VALUE;
302     }
303 
304     srcImgInfo.width = dstImgInfo.width;
305     srcImgInfo.height = dstImgInfo.height;
306     srcImgInfo.alignedWidth = dstImgInfo.alignedWidth;
307     srcImgInfo.alignedHeight = dstImgInfo.alignedHeight;
308     srcImgInfo.chromaOffset = static_cast<size_t>(srcImgInfo.alignedWidth * srcImgInfo.alignedHeight);
309     srcImgInfo.imgSize = dstBuf->Size();
310 
311     DHLOGD("Convert I420 scale success.");
312     return DCAMERA_OK;
313 }
314 
ConvertFormatToNV21(ImageUnitInfo & srcImgInfo,ImageUnitInfo & dstImgInfo,std::shared_ptr<DataBuffer> & dstBuf)315 int32_t ScaleConvertProcess::ConvertFormatToNV21(ImageUnitInfo& srcImgInfo, ImageUnitInfo& dstImgInfo,
316     std::shared_ptr<DataBuffer>& dstBuf)
317 {
318     CHECK_AND_RETURN_RET_LOG((dstBuf == nullptr), DCAMERA_BAD_VALUE, "Buffer is null.");
319     CHECK_AND_RETURN_RET_LOG((dstImgInfo.imgData == nullptr), DCAMERA_BAD_VALUE, "Image data is null.");
320     if (srcImgInfo.colorFormat == dstImgInfo.colorFormat) {
321         DHLOGD("Convert format to NV21 srcImgInfo format is the same as dstImgInfo format");
322         return DCAMERA_OK;
323     }
324 
325     DHLOGD("Convert I420 to NV21: format=%{public}d, width=[%{public}d, %{public}d], height=[%{public}d, %{public}d]",
326         srcImgInfo.colorFormat, srcImgInfo.width, srcImgInfo.alignedWidth, srcImgInfo.height,
327         srcImgInfo.alignedHeight);
328     int srcSizeY = srcImgInfo.width * srcImgInfo.height;
329     int srcSizeUV = (static_cast<uint32_t>(srcImgInfo.width) >> MEMORY_RATIO_UV) *
330                     (static_cast<uint32_t>(srcImgInfo.height) >> MEMORY_RATIO_UV);
331     uint8_t *srcDataY = dstBuf->Data();
332     uint8_t *srcDataU = dstBuf->Data() + srcSizeY;
333     uint8_t *srcDataV = dstBuf->Data() + srcSizeY + srcSizeUV;
334 
335     int dstSizeY = dstImgInfo.width * dstImgInfo.height;
336     uint8_t *dstDataY = dstImgInfo.imgData->Data();
337     uint8_t *dstDataUV = dstImgInfo.imgData->Data() + dstSizeY;
338 
339     auto converter = ConverterHandle::GetInstance().GetHandle();
340     CHECK_AND_RETURN_RET_LOG(converter.I420ToNV21 == nullptr, DCAMERA_BAD_VALUE, "converter is invalid.");
341     int32_t ret = converter.I420ToNV21(
342         srcDataY, srcImgInfo.width,
343         srcDataU, static_cast<uint32_t>(srcImgInfo.width) >> MEMORY_RATIO_UV,
344         srcDataV, static_cast<uint32_t>(srcImgInfo.width) >> MEMORY_RATIO_UV,
345         dstDataY, dstImgInfo.width,
346         dstDataUV, dstImgInfo.width,
347         dstImgInfo.width, dstImgInfo.height);
348     if (ret != DCAMERA_OK) {
349         DHLOGE("Convert I420 to NV21 failed.");
350         return DCAMERA_BAD_VALUE;
351     }
352 
353     DHLOGD("Convert I420 to NV21 success.");
354     return DCAMERA_OK;
355 }
356 
ConvertFormatToRGBA(ImageUnitInfo & srcImgInfo,ImageUnitInfo & dstImgInfo,std::shared_ptr<DataBuffer> & dstBuf)357 int32_t ScaleConvertProcess::ConvertFormatToRGBA(ImageUnitInfo& srcImgInfo, ImageUnitInfo& dstImgInfo,
358     std::shared_ptr<DataBuffer>& dstBuf)
359 {
360     CHECK_AND_RETURN_RET_LOG((dstBuf == nullptr), DCAMERA_BAD_VALUE, "Buffer is null.");
361     CHECK_AND_RETURN_RET_LOG((dstImgInfo.imgData == nullptr), DCAMERA_BAD_VALUE, "Image data is null.");
362     if (srcImgInfo.colorFormat == dstImgInfo.colorFormat) {
363         DHLOGD("Convert format to RGBA srcImgInfo format is the same as dstImgInfo format");
364         return DCAMERA_OK;
365     }
366 
367     DHLOGI("Convert I420 to RGBA: format=%{public}d, width=[%{public}d, %{public}d], height=[%{public}d, %{public}d]",
368         srcImgInfo.colorFormat, srcImgInfo.width, srcImgInfo.alignedWidth, srcImgInfo.height, srcImgInfo.alignedHeight);
369     int srcSizeY = srcImgInfo.width * srcImgInfo.height;
370     int srcSizeUV = (static_cast<uint32_t>(srcImgInfo.width) >> MEMORY_RATIO_UV) *
371                     (static_cast<uint32_t>(srcImgInfo.height) >> MEMORY_RATIO_UV);
372     uint8_t *srcDataY = dstBuf->Data();
373     uint8_t *srcDataU = dstBuf->Data() + srcSizeY;
374     uint8_t *srcDataV = dstBuf->Data() + srcSizeY + srcSizeUV;
375 
376     uint8_t *dstDataRGBA = dstImgInfo.imgData->Data();
377     auto converter = ConverterHandle::GetInstance().GetHandle();
378     CHECK_AND_RETURN_RET_LOG(converter.I420ToRGBA == nullptr, DCAMERA_BAD_VALUE, "converter is invalid.");
379     int32_t ret = converter.I420ToRGBA(
380         srcDataY, srcImgInfo.width,
381         srcDataU, static_cast<uint32_t>(srcImgInfo.width) >> MEMORY_RATIO_UV,
382         srcDataV, static_cast<uint32_t>(srcImgInfo.width) >> MEMORY_RATIO_UV,
383         dstDataRGBA, dstImgInfo.width * RGB32_MEMORY_COEFFICIENT,
384         dstImgInfo.width, dstImgInfo.height);
385     if (ret != DCAMERA_OK) {
386         DHLOGE("Convert I420 to RGBA failed.");
387         return DCAMERA_BAD_VALUE;
388     }
389 
390     DHLOGD("Convert I420 to RGBA success.");
391     return DCAMERA_OK;
392 }
393 
ConvertDone(std::vector<std::shared_ptr<DataBuffer>> & outputBuffers)394 int32_t ScaleConvertProcess::ConvertDone(std::vector<std::shared_ptr<DataBuffer>>& outputBuffers)
395 {
396     int64_t finishScaleTime = GetNowTimeStampUs();
397     DHLOGD("ScaleConvertProcess : Convert Done.");
398     if (outputBuffers.empty() || outputBuffers[0] == nullptr) {
399         DHLOGE("The received data buffer is empty.");
400         return DCAMERA_BAD_VALUE;
401     }
402     outputBuffers[0]->frameInfo_.timePonit.finishScale = finishScaleTime;
403 
404     if (nextDataProcess_ != nullptr) {
405         DHLOGD("Send to the next node of the scale convert for processing.");
406         int32_t err = nextDataProcess_->ProcessData(outputBuffers);
407         if (err != DCAMERA_OK) {
408             DHLOGE("Some node after the scale convert processes failed.");
409         }
410         return err;
411     }
412 
413     DHLOGD("The current node is the last noed, and output the processed video buffer.");
414     std::shared_ptr<DCameraPipelineSource> targetPipelineSource = callbackPipelineSource_.lock();
415     if (targetPipelineSource == nullptr) {
416         DHLOGE("callbackPipelineSource_ is nullptr.");
417         return DCAMERA_BAD_VALUE;
418     }
419     targetPipelineSource->OnProcessedVideoBuffer(outputBuffers[0]);
420     return DCAMERA_OK;
421 }
422 
GetProperty(const std::string & propertyName,PropertyCarrier & propertyCarrier)423 int32_t ScaleConvertProcess::GetProperty(const std::string& propertyName, PropertyCarrier& propertyCarrier)
424 {
425     return DCAMERA_OK;
426 }
427 } // namespace DistributedHardware
428 } // namespace OHOS
429