1 /*
2  * Copyright (c) 2023-2023 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 "video_post_processor.h"
17 
18 #include <sys/sendfile.h>
19 #include <sys/stat.h>
20 
21 #include "dp_log.h"
22 #include "dp_timer.h"
23 #include "dps.h"
24 #include "dps_event_report.h"
25 #include "events_monitor.h"
26 #include "hdf_device_class.h"
27 #include "iproxy_broker.h"
28 #include "iservmgr_hdi.h"
29 #include "mpeg_manager_factory.h"
30 #include "service_died_command.h"
31 #include "video_process_command.h"
32 
33 namespace OHOS {
34 namespace CameraStandard {
35 namespace DeferredProcessing {
36 namespace {
37     const std::string VIDEO_SERVICE_NAME = "camera_video_process_service";
38     constexpr uint32_t MAX_PROC_TIME_MS = 20 * 60 * 1000;
39 }
40 
41 class VideoPostProcessor::VideoServiceListener : public HDI::ServiceManager::V1_0::ServStatListenerStub {
42 public:
43     using StatusCallback = std::function<void(const HDI::ServiceManager::V1_0::ServiceStatus&)>;
VideoServiceListener(const std::weak_ptr<VideoPostProcessor> & processor)44     explicit VideoServiceListener(const std::weak_ptr<VideoPostProcessor>& processor) : processor_(processor)
45     {
46     }
47 
OnReceive(const HDI::ServiceManager::V1_0::ServiceStatus & status)48     void OnReceive(const HDI::ServiceManager::V1_0::ServiceStatus& status)
49     {
50         auto process = processor_.lock();
51         DP_CHECK_ERROR_RETURN_LOG(process == nullptr, "post process is nullptr.");
52         process->OnServiceChange(status);
53     }
54 
55 private:
56     std::weak_ptr<VideoPostProcessor> processor_;
57 };
58 
59 class VideoPostProcessor::SessionDeathRecipient : public IRemoteObject::DeathRecipient {
60 public:
SessionDeathRecipient(const std::weak_ptr<VideoPostProcessor> & processor)61     explicit SessionDeathRecipient(const std::weak_ptr<VideoPostProcessor>& processor) : processor_(processor)
62     {
63     }
64 
OnRemoteDied(const wptr<IRemoteObject> & remote)65     void OnRemoteDied(const wptr<IRemoteObject> &remote) override
66     {
67         DP_ERR_LOG("Remote died.");
68         auto process = processor_.lock();
69         DP_CHECK_ERROR_RETURN_LOG(process == nullptr, "post process is nullptr.");
70         process->OnSessionDied();
71     }
72 
73 private:
74     std::weak_ptr<VideoPostProcessor> processor_;
75 };
76 
77 class VideoPostProcessor::VideoProcessListener : public OHOS::HDI::Camera::V1_3::IVideoProcessCallback {
78 public:
VideoProcessListener(const std::weak_ptr<VideoPostProcessor> & processor)79     explicit VideoProcessListener(const std::weak_ptr<VideoPostProcessor>& processor) : processor_(processor)
80     {
81     }
82 
83     int32_t OnStatusChanged(OHOS::HDI::Camera::V1_2::SessionStatus status) override;
84     int32_t OnProcessDone(const std::string& videoId) override;
85     int32_t OnError(const std::string& videoId, OHOS::HDI::Camera::V1_2::ErrorCode errorCode) override;
86     void ReportEvent(const std::string& videoId);
87 
88 private:
89     std::weak_ptr<VideoPostProcessor> processor_;
90 };
91 
OnStatusChanged(OHOS::HDI::Camera::V1_2::SessionStatus status)92 int32_t VideoPostProcessor::VideoProcessListener::OnStatusChanged(OHOS::HDI::Camera::V1_2::SessionStatus status)
93 {
94     DP_DEBUG_LOG("entered");
95     auto process = processor_.lock();
96     DP_CHECK_ERROR_RETURN_RET_LOG(process == nullptr, DP_ERR, "post process is nullptr.");
97     return DP_OK;
98 }
99 
OnProcessDone(const std::string & videoId)100 int32_t VideoPostProcessor::VideoProcessListener::OnProcessDone(const std::string& videoId)
101 {
102     DP_INFO_LOG("entered, videoId: %{public}s", videoId.c_str());
103     auto process = processor_.lock();
104     DP_CHECK_ERROR_RETURN_RET_LOG(process == nullptr, DP_ERR, "post process is nullptr.");
105     process->OnProcessDone(videoId);
106     return DP_OK;
107 }
108 
OnError(const std::string & videoId,OHOS::HDI::Camera::V1_2::ErrorCode errorCode)109 int32_t VideoPostProcessor::VideoProcessListener::OnError(const std::string& videoId,
110     OHOS::HDI::Camera::V1_2::ErrorCode errorCode)
111 {
112     DP_INFO_LOG("entered, videoId: %{public}s, error: %{public}d", videoId.c_str(), errorCode);
113     auto process = processor_.lock();
114     DP_CHECK_ERROR_RETURN_RET_LOG(process == nullptr, DP_ERR, "post process is nullptr.");
115     process->OnError(videoId, process->MapHdiError(errorCode));
116     return DP_OK;
117 }
118 
VideoPostProcessor(const int32_t userId)119 VideoPostProcessor::VideoPostProcessor(const int32_t userId)
120     : userId_(userId), serviceListener_(nullptr), sessionDeathRecipient_(nullptr), processListener_(nullptr)
121 {
122     DP_DEBUG_LOG("entered");
123 }
124 
~VideoPostProcessor()125 VideoPostProcessor::~VideoPostProcessor()
126 {
127     DP_DEBUG_LOG("entered");
128     DisconnectService();
129     SetVideoSession(nullptr);
130     allStreamInfo_.clear();
131     videoId2Handle_.Clear();
132 }
133 
Initialize()134 void VideoPostProcessor::Initialize()
135 {
136     DP_DEBUG_LOG("entered");
137     sessionDeathRecipient_ = sptr<SessionDeathRecipient>::MakeSptr(weak_from_this());
138     processListener_ = sptr<VideoProcessListener>::MakeSptr(weak_from_this());
139     ConnectService();
140 }
141 
GetPendingVideos(std::vector<std::string> & pendingVideos)142 bool VideoPostProcessor::GetPendingVideos(std::vector<std::string>& pendingVideos)
143 {
144     auto session = GetVideoSession();
145     DP_CHECK_ERROR_RETURN_RET_LOG(session == nullptr, false, "video session is nullptr.");
146     int32_t ret = session->GetPendingVideos(pendingVideos);
147     DP_INFO_LOG("GetPendingVideos size: %{public}d, ret: %{public}d",
148         static_cast<int32_t>(pendingVideos.size()), ret);
149     return ret == DP_OK;
150 }
151 
SetExecutionMode(ExecutionMode executionMode)152 void VideoPostProcessor::SetExecutionMode(ExecutionMode executionMode)
153 {
154     DP_DEBUG_LOG("entered.");
155 }
156 
SetDefaultExecutionMode()157 void VideoPostProcessor::SetDefaultExecutionMode()
158 {
159     DP_DEBUG_LOG("entered.");
160 }
161 
ProcessRequest(const DeferredVideoWorkPtr & work)162 void VideoPostProcessor::ProcessRequest(const DeferredVideoWorkPtr& work)
163 {
164     auto session = GetVideoSession();
165     auto videoId = work->GetDeferredVideoJob()->GetVideoId();
166     if (session == nullptr) {
167         DP_ERR_LOG("failed to process videoId: %{public}s, video session is nullptr", videoId.c_str());
168         OnError(videoId, DpsError::DPS_ERROR_SESSION_NOT_READY_TEMPORARILY);
169         return;
170     }
171 
172     auto inFd = work->GetDeferredVideoJob()->GetInputFd();
173     DP_CHECK_ERROR_RETURN_LOG(!StartMpeg(videoId, inFd), "mpeg start failed.");
174     DP_CHECK_ERROR_RETURN_LOG(!PrepareStreams(videoId, inFd->GetFd()), "prepaer video failed.");
175 
176     StartTimer(videoId, work);
177     auto mpegManager = GetMpegManager();
178     DP_CHECK_ERROR_RETURN_LOG(!mpegManager, "mpegManager is nullptr");
179     auto startTime = mpegManager->GetProcessTimeStamp();
180     auto ret = session->ProcessVideo(videoId, startTime);
181     DP_INFO_LOG("process video to ive, videoId: %{public}s, startTime: %{public}llu, ret: %{public}d",
182         videoId.c_str(), static_cast<unsigned long long>(startTime), ret);
183 }
184 
RemoveRequest(const std::string & videoId)185 void VideoPostProcessor::RemoveRequest(const std::string& videoId)
186 {
187     auto session = GetVideoSession();
188     DP_CHECK_ERROR_RETURN_LOG(session == nullptr,
189         "remove videoId: %{public}s failed, video session is nullptr.", videoId.c_str());
190     std::string path = PATH + videoId + OUT_TAG;
191     DP_CHECK_ERROR_PRINT_LOG(remove(path.c_str()) != 0, "Failed to remove file at path: %{public}s", path.c_str());
192     auto ret = session->RemoveVideo(videoId);
193     DP_INFO_LOG("remove video to ive, videoId: %{public}s, ret: %{public}d", videoId.c_str(), ret);
194     // DPSEventReport::GetInstance().UpdateRemoveTime(imageId, userId_);
195 }
196 
PauseRequest(const std::string & videoId,const ScheduleType & type)197 void VideoPostProcessor::PauseRequest(const std::string& videoId, const ScheduleType& type)
198 {
199     auto session = GetVideoSession();
200     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "video session is nullptr.");
201 
202     int32_t ret = session->Interrupt();
203     DP_INFO_LOG("interrupt video to ive, videoId: %{public}s, ret: %{public}d", videoId.c_str(), ret);
204     // DPSEventReport::GetInstance().UpdateRemoveTime(imageId, userId_);
205 }
206 
PrepareStreams(const std::string & videoId,const int inputFd)207 bool VideoPostProcessor::PrepareStreams(const std::string& videoId, const int inputFd)
208 {
209     auto session = GetVideoSession();
210     DP_CHECK_ERROR_RETURN_RET_LOG(session == nullptr, false, "video session is nullptr.");
211     allStreamInfo_.clear();
212     std::vector<StreamDescription> streamDescs;
213     auto ret = session->Prepare(videoId, inputFd, streamDescs);
214     DP_INFO_LOG("prepare videoId: %{public}s, stream size: %{public}d, ret: %{public}d", videoId.c_str(),
215         static_cast<int32_t>(streamDescs.size()), ret);
216     for (const auto& stream : streamDescs) {
217         DP_INFO_LOG("streamId: %{public}d, stream type: %{public}d", stream.streamId, stream.type);
218         if (stream.type == 0) {
219             auto mpegManager = GetMpegManager();
220             DP_CHECK_ERROR_RETURN_RET_LOG(!mpegManager, false, "mpegManager is nullptr");
221             auto producer = sptr<BufferProducerSequenceable>::MakeSptr(mpegManager->GetSurface()->GetProducer());
222             SetStreamInfo(stream, producer);
223         }
224     }
225 
226     DP_INFO_LOG("prepare videoId: %{public}s, allStreamInfo size: %{public}d", videoId.c_str(),
227         static_cast<int32_t>(allStreamInfo_.size()));
228     DP_CHECK_ERROR_RETURN_RET_LOG(allStreamInfo_.empty(), false, "allStreamInfo is null.");
229     ret = session->CreateStreams(allStreamInfo_);
230     DP_INFO_LOG("create streams videoId: %{public}s, ret: %{public}d", videoId.c_str(), ret);
231     std::vector<uint8_t> modeSetting;
232     ret = session->CommitStreams(modeSetting);
233     DP_INFO_LOG("commit streams videoId: %{public}s, ret: %{public}d", videoId.c_str(), ret);
234     return true;
235 }
236 
CreateSurface(const std::string & name,const StreamDescription & stream,sptr<Surface> & surface)237 void VideoPostProcessor::CreateSurface(const std::string& name, const StreamDescription& stream,
238     sptr<Surface>& surface)
239 {
240     DP_INFO_LOG("entered, create %{public}s surface.", name.c_str());
241     surface = Surface::CreateSurfaceAsConsumer(name);
242     surface->SetDefaultUsage(BUFFER_USAGE_VIDEO_ENCODER);
243     surface->SetDefaultWidthAndHeight(stream.width, stream.height);
244     auto producer = sptr<BufferProducerSequenceable>::MakeSptr(surface->GetProducer());
245     SetStreamInfo(stream, producer);
246 }
247 
SetStreamInfo(const StreamDescription & stream,sptr<BufferProducerSequenceable> & producer)248 void VideoPostProcessor::SetStreamInfo(const StreamDescription& stream, sptr<BufferProducerSequenceable>& producer)
249 {
250     StreamInfo_V1_1 streamInfo;
251     streamInfo.v1_0.intent_ = HDI::Camera::V1_0::VIDEO;
252     streamInfo.v1_0.tunneledMode_ = true;
253     streamInfo.v1_0.streamId_ = stream.streamId;
254     streamInfo.v1_0.width_ = stream.width;
255     streamInfo.v1_0.height_ = stream.height;
256     streamInfo.v1_0.format_ = stream.pixelFormat;
257     streamInfo.v1_0.dataspace_ = stream.dataspace;
258     streamInfo.v1_0.bufferQueue_ = producer;
259     allStreamInfo_.emplace_back(streamInfo);
260 }
261 
StartMpeg(const std::string & videoId,const sptr<IPCFileDescriptor> & inputFd)262 bool VideoPostProcessor::StartMpeg(const std::string& videoId, const sptr<IPCFileDescriptor>& inputFd)
263 {
264     auto mpegManager = MpegManagerFactory::GetInstance().Acquire(videoId, inputFd);
265     SetMpegManager(mpegManager);
266     DP_CHECK_ERROR_RETURN_RET_LOG(mpegManager == nullptr, false, "mpeg manager is nullptr.");
267     return true;
268 }
269 
StopMpeg(const MediaResult result,const DeferredVideoWorkPtr & work)270 bool VideoPostProcessor::StopMpeg(const MediaResult result, const DeferredVideoWorkPtr& work)
271 {
272     auto mpegManager = GetMpegManager();
273     DP_CHECK_ERROR_RETURN_RET_LOG(mpegManager == nullptr, false, "mpegManager is nullptr");
274     mpegManager->UnInit(result);
275 
276     bool ret = true;
277     if (result == MediaResult::SUCCESS) {
278         auto tempFd = mpegManager->GetResultFd()->GetFd();
279         auto outFd = work->GetDeferredVideoJob()->GetOutputFd()->GetFd();
280         auto videoId = work->GetDeferredVideoJob()->GetVideoId();
281         DP_INFO_LOG("video process done, videoId: %{public}s, tempFd: %{public}d, outFd: %{public}d",
282             videoId.c_str(), tempFd, outFd);
283         copyFileByFd(tempFd, outFd);
284         if (IsFileEmpty(outFd)) {
285             DP_ERR_LOG("videoId: %{public}s size is empty.", videoId.c_str());
286             OnError(videoId, DPS_ERROR_VIDEO_PROC_FAILED);
287             ret = false;
288         }
289     }
290     ReleaseMpeg();
291     return ret;
292 }
293 
ReleaseMpeg()294 void VideoPostProcessor::ReleaseMpeg()
295 {
296     auto mpegManager = GetMpegManager();
297     DP_CHECK_ERROR_RETURN_LOG(mpegManager == nullptr, "mpegManager is nullptr");
298     MpegManagerFactory::GetInstance().Release(mpegManager);
299     mpegManager.reset();
300     SetMpegManager(nullptr);
301     DP_INFO_LOG("release mpeg success.");
302 }
303 
StartTimer(const std::string & videoId,const DeferredVideoWorkPtr & work)304 void VideoPostProcessor::StartTimer(const std::string& videoId, const DeferredVideoWorkPtr& work)
305 {
306     uint32_t timeId = DpsTimer::GetInstance().StartTimer([&, videoId]() {OnTimerOut(videoId);}, MAX_PROC_TIME_MS);
307     work->SetTimeId(timeId);
308     DP_INFO_LOG("DpsTimer start, videoId: %{public}s, timeId: %{public}u", videoId.c_str(), timeId);
309     videoId2Handle_.Insert(videoId, work);
310 }
311 
StopTimer(const std::string & videoId)312 void VideoPostProcessor::StopTimer(const std::string& videoId)
313 {
314     DeferredVideoWorkPtr work;
315     DP_CHECK_RETURN(!videoId2Handle_.Find(videoId, work));
316 
317     auto timeId = work->GetTimeId();
318     DP_INFO_LOG("DpsTimer stop, videoId: %{public}s, timeId: %{public}u", videoId.c_str(), timeId);
319     DpsTimer::GetInstance().StopTimer(timeId);
320     auto session = GetVideoSession();
321     DP_CHECK_ERROR_RETURN_LOG(session == nullptr,
322         "release videoId: %{public}s failed, video session is nullptr.", videoId.c_str());
323 
324     auto ret = session->ReleaseStreams(allStreamInfo_);
325     allStreamInfo_.clear();
326     DP_INFO_LOG("release streams videoId: %{public}s, ret: %{public}d", videoId.c_str(), ret);
327 }
328 
GetRunningWork(const std::string & videoId)329 DeferredVideoWorkPtr VideoPostProcessor::GetRunningWork(const std::string& videoId)
330 {
331     DeferredVideoWorkPtr work;
332     videoId2Handle_.Find(videoId, work);
333     return work;
334 }
335 
OnSessionDied()336 void VideoPostProcessor::OnSessionDied()
337 {
338     DP_ERR_LOG("entered, session died!");
339     SetVideoSession(nullptr);
340 
341     std::vector<std::string> crashJobs;
342     videoId2Handle_.Iterate([&](const std::string& videoId, const DeferredVideoWorkPtr& work) {
343         crashJobs.emplace_back(work->GetDeferredVideoJob()->GetVideoId());
344     });
345     for (const auto& id : crashJobs) {
346         OnError(id, DPS_ERROR_VIDEO_PROC_INTERRUPTED);
347     }
348     crashJobs.clear();
349     auto ret = DPS_SendCommand<ServiceDiedCommand>(userId_);
350     DP_CHECK_ERROR_PRINT_LOG(ret != DP_OK, "failed. ret: %{public}d", ret);
351 }
352 
OnProcessDone(const std::string & videoId)353 void VideoPostProcessor::OnProcessDone(const std::string& videoId)
354 {
355     auto work = GetRunningWork(videoId);
356     DP_CHECK_ERROR_RETURN_LOG(work == nullptr, "not find running video work.");
357     StopTimer(videoId);
358     DP_CHECK_ERROR_RETURN_LOG(!StopMpeg(MediaResult::SUCCESS, work), "success: mpeg stop failed.");
359 
360     auto ret = DPS_SendCommand<VideoProcessSuccessCommand>(userId_, work);
361     DP_CHECK_ERROR_RETURN_LOG(ret != DP_OK,
362         "process success videoId: %{public}s failed. ret: %{public}d", videoId.c_str(), ret);
363     videoId2Handle_.Erase(videoId);
364 }
365 
OnError(const std::string & videoId,DpsError errorCode)366 void VideoPostProcessor::OnError(const std::string& videoId, DpsError errorCode)
367 {
368     auto work = GetRunningWork(videoId);
369     StopTimer(videoId);
370     DP_CHECK_ERROR_RETURN_LOG(work == nullptr, "no running video work.");
371 
372     if (errorCode == DPS_ERROR_VIDEO_PROC_INTERRUPTED) {
373         DP_CHECK_ERROR_RETURN_LOG(!StopMpeg(MediaResult::PAUSE, work), "pause: mpeg stop failed.");
374     } else {
375         DP_CHECK_ERROR_RETURN_LOG(!StopMpeg(MediaResult::FAIL, work), "error or outtime: mpeg stop failed.");
376     }
377 
378     DP_INFO_LOG("video process error, videoId: %{public}s, error: %{public}d", videoId.c_str(), errorCode);
379     auto ret = DPS_SendCommand<VideoProcessFailedCommand>(userId_, work, errorCode);
380     DP_CHECK_ERROR_RETURN_LOG(ret != DP_OK,
381         "process error videoId: %{public}s failed. ret: %{public}d", videoId.c_str(), ret);
382     videoId2Handle_.Erase(videoId);
383 }
384 
OnStateChanged(HdiStatus hdiStatus)385 void VideoPostProcessor::OnStateChanged(HdiStatus hdiStatus)
386 {
387     DP_INFO_LOG("entered, HdiStatus: %{public}d", hdiStatus);
388     EventsMonitor::GetInstance().NotifyImageEnhanceStatus(hdiStatus);
389 }
390 
OnTimerOut(const std::string & videoId)391 void VideoPostProcessor::OnTimerOut(const std::string& videoId)
392 {
393     DP_INFO_LOG("DpsTimer executed, videoId: %{public}s", videoId.c_str());
394     OnError(videoId, DpsError::DPS_ERROR_IMAGE_PROC_TIMEOUT);
395 }
396 
ConnectService()397 void VideoPostProcessor::ConnectService()
398 {
399     auto svcMgr = HDI::ServiceManager::V1_0::IServiceManager::Get();
400     DP_CHECK_ERROR_RETURN_LOG(svcMgr == nullptr, "IServiceManager init failed.");
401 
402     serviceListener_ = sptr<VideoServiceListener>::MakeSptr(weak_from_this());
403     auto ret  = svcMgr->RegisterServiceStatusListener(serviceListener_, DEVICE_CLASS_DEFAULT);
404     DP_CHECK_ERROR_RETURN_LOG(ret != 0, "RegisterServiceStatusListener failed.");
405 }
406 
DisconnectService()407 void VideoPostProcessor::DisconnectService()
408 {
409     auto session = GetVideoSession();
410     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "video session is nullptr.");
411 
412     const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<IVideoProcessSession>(session);
413     bool result = remote->RemoveDeathRecipient(sessionDeathRecipient_);
414     DP_CHECK_ERROR_RETURN_LOG(!result, "remove DeathRecipient for VideoProcessSession failed.");
415 
416     auto svcMgr = HDI::ServiceManager::V1_0::IServiceManager::Get();
417     DP_CHECK_ERROR_RETURN_LOG(svcMgr == nullptr, "IServiceManager init failed.");
418 
419     auto ret  = svcMgr->UnregisterServiceStatusListener(serviceListener_);
420     DP_CHECK_ERROR_RETURN_LOG(ret != 0, "RegisterServiceStatusListener failed.");
421 }
422 
OnServiceChange(const HDI::ServiceManager::V1_0::ServiceStatus & status)423 void VideoPostProcessor::OnServiceChange(const HDI::ServiceManager::V1_0::ServiceStatus& status)
424 {
425     DP_CHECK_RETURN(status.serviceName != VIDEO_SERVICE_NAME);
426     DP_CHECK_RETURN_LOG(status.status != HDI::ServiceManager::V1_0::SERVIE_STATUS_START,
427         "video service state: %{public}d", status.status);
428     DP_CHECK_RETURN(GetVideoSession() != nullptr);
429 
430     sptr<HDI::Camera::V1_3::IVideoProcessService> proxy =
431         HDI::Camera::V1_3::IVideoProcessService::Get(status.serviceName);
432     DP_CHECK_ERROR_RETURN_LOG(proxy == nullptr, "get VideoProcessService failed.");
433 
434     sptr<IVideoProcessSession> session;
435     proxy->CreateVideoProcessSession(userId_, processListener_, session);
436     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "get VideoProcessSession failed.");
437 
438     const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<IVideoProcessSession>(session);
439     bool result = remote->AddDeathRecipient(sessionDeathRecipient_);
440     DP_CHECK_ERROR_RETURN_LOG(!result, "add DeathRecipient for VideoProcessSession failed.");
441 
442     SetVideoSession(session);
443     OnStateChanged(HdiStatus::HDI_READY);
444 }
445 
copyFileByFd(const int srcFd,const int dstFd)446 void VideoPostProcessor::copyFileByFd(const int srcFd, const int dstFd)
447 {
448     struct stat buffer;
449     DP_CHECK_ERROR_RETURN_LOG(fstat(srcFd, &buffer) == -1,
450         "get out fd status failed, err: %{public}s", std::strerror(errno));
451 
452     off_t offset = 0;
453     ssize_t bytesSent;
454     while (offset < buffer.st_size) {
455         bytesSent = sendfile(dstFd, srcFd, &offset, buffer.st_size - offset);
456         DP_CHECK_ERROR_RETURN_LOG(bytesSent == -1, "copy file failed, err: %{public}s", std::strerror(errno));
457     }
458 }
459 
MapHdiError(OHOS::HDI::Camera::V1_2::ErrorCode errorCode)460 DpsError VideoPostProcessor::MapHdiError(OHOS::HDI::Camera::V1_2::ErrorCode errorCode)
461 {
462     DpsError code = DpsError::DPS_ERROR_UNKNOW;
463     switch (errorCode) {
464         case OHOS::HDI::Camera::V1_2::ErrorCode::ERROR_INVALID_ID:
465             code = DpsError::DPS_ERROR_VIDEO_PROC_INVALID_VIDEO_ID;
466             break;
467         case OHOS::HDI::Camera::V1_2::ErrorCode::ERROR_PROCESS:
468             code = DpsError::DPS_ERROR_VIDEO_PROC_FAILED;
469             break;
470         case OHOS::HDI::Camera::V1_2::ErrorCode::ERROR_TIMEOUT:
471             code = DpsError::DPS_ERROR_VIDEO_PROC_TIMEOUT;
472             break;
473         case OHOS::HDI::Camera::V1_2::ErrorCode::ERROR_ABORT:
474             code = DpsError::DPS_ERROR_VIDEO_PROC_INTERRUPTED;
475             break;
476         default:
477             DP_ERR_LOG("unexpected error code: %{public}d.", errorCode);
478             break;
479     }
480     return code;
481 }
482 } // namespace DeferredProcessing
483 } // namespace CameraStandard
484 } // namespace OHOS