• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-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 "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 "events_info.h"
25 #include "events_monitor.h"
26 #include "hdf_device_class.h"
27 #include "iproxy_broker.h"
28 #include "iservmgr_hdi.h"
29 
30 namespace OHOS {
31 namespace CameraStandard {
32 namespace DeferredProcessing {
33 namespace {
34     const std::string VIDEO_SERVICE_NAME = "camera_video_process_service";
35     constexpr uint32_t MAX_PROC_TIME_MS = 20 * 60 * 1000;
36 }
37 
38 // LCOV_EXCL_START
MapHdiVideoStatus(OHOS::HDI::Camera::V1_2::SessionStatus statusCode)39 HdiStatus MapHdiVideoStatus(OHOS::HDI::Camera::V1_2::SessionStatus statusCode)
40 {
41     HdiStatus code = HdiStatus::HDI_DISCONNECTED;
42     switch (statusCode) {
43         case OHOS::HDI::Camera::V1_2::SessionStatus::SESSION_STATUS_READY:
44             code = HdiStatus::HDI_READY;
45             break;
46         case OHOS::HDI::Camera::V1_2::SessionStatus::SESSION_STATUS_READY_SPACE_LIMIT_REACHED:
47             code = HdiStatus::HDI_READY_SPACE_LIMIT_REACHED;
48             break;
49         case OHOS::HDI::Camera::V1_2::SessionStatus::SESSSON_STATUS_NOT_READY_TEMPORARILY:
50             code = HdiStatus::HDI_NOT_READY_TEMPORARILY;
51             break;
52         case OHOS::HDI::Camera::V1_2::SessionStatus::SESSION_STATUS_NOT_READY_OVERHEAT:
53             code = HdiStatus::HDI_NOT_READY_OVERHEAT;
54             break;
55         case OHOS::HDI::Camera::V1_2::SessionStatus::SESSION_STATUS_NOT_READY_PREEMPTED:
56             code = HdiStatus::HDI_NOT_READY_PREEMPTED;
57             break;
58         default:
59             DP_ERR_LOG("unexpected error code: %{public}d.", statusCode);
60             break;
61     }
62     return code;
63 }
64 // LCOV_EXCL_STOP
65 
66 // LCOV_EXCL_START
MapHdiVideoError(OHOS::HDI::Camera::V1_2::ErrorCode errorCode)67 DpsError MapHdiVideoError(OHOS::HDI::Camera::V1_2::ErrorCode errorCode)
68 {
69     DpsError code = DPS_ERROR_UNKNOW;
70     switch (errorCode) {
71         case OHOS::HDI::Camera::V1_2::ErrorCode::ERROR_INVALID_ID:
72             code = DPS_ERROR_VIDEO_PROC_INVALID_VIDEO_ID;
73             break;
74         case OHOS::HDI::Camera::V1_2::ErrorCode::ERROR_PROCESS:
75             code = DPS_ERROR_VIDEO_PROC_FAILED;
76             break;
77         case OHOS::HDI::Camera::V1_2::ErrorCode::ERROR_TIMEOUT:
78             code = DPS_ERROR_VIDEO_PROC_TIMEOUT;
79             break;
80         case OHOS::HDI::Camera::V1_2::ErrorCode::ERROR_ABORT:
81             code = DPS_ERROR_VIDEO_PROC_INTERRUPTED;
82             break;
83         default:
84             DP_ERR_LOG("unexpected error code: %{public}d.", errorCode);
85             break;
86     }
87     return code;
88 }
89 // LCOV_EXCL_STOP
90 
91 class VideoPostProcessor::VideoServiceListener : public HDI::ServiceManager::V1_0::ServStatListenerStub {
92 public:
93     using StatusCallback = std::function<void(const HDI::ServiceManager::V1_0::ServiceStatus&)>;
VideoServiceListener(const std::weak_ptr<VideoPostProcessor> & processor)94     explicit VideoServiceListener(const std::weak_ptr<VideoPostProcessor>& processor) : processor_(processor)
95     {
96         DP_DEBUG_LOG("entered.");
97     }
98 
OnReceive(const HDI::ServiceManager::V1_0::ServiceStatus & status)99     void OnReceive(const HDI::ServiceManager::V1_0::ServiceStatus& status)
100     {
101         auto process = processor_.lock();
102         DP_CHECK_ERROR_RETURN_LOG(process == nullptr, "post process is nullptr.");
103         process->OnServiceChange(status);
104     }
105 
106 private:
107     std::weak_ptr<VideoPostProcessor> processor_;
108 };
109 
110 class VideoPostProcessor::SessionDeathRecipient : public IRemoteObject::DeathRecipient {
111 public:
SessionDeathRecipient(const std::weak_ptr<VideoProcessResult> & processResult)112     explicit SessionDeathRecipient(const std::weak_ptr<VideoProcessResult>& processResult)
113         : processResult_(processResult)
114     {
115         DP_DEBUG_LOG("entered.");
116     }
117     // LCOV_EXCL_START
OnRemoteDied(const wptr<IRemoteObject> & remote)118     void OnRemoteDied(const wptr<IRemoteObject> &remote) override
119     {
120         auto processResult = processResult_.lock();
121         DP_CHECK_ERROR_RETURN_LOG(processResult == nullptr, "VideoProcessResult is nullptr.");
122 
123         processResult->OnVideoSessionDied();
124     }
125     // LCOV_EXCL_STOP
126 
127 private:
128     std::weak_ptr<VideoProcessResult> processResult_;
129 };
130 
131 class VideoPostProcessor::VideoProcessListener : public HDI::Camera::V1_4::IVideoProcessCallback {
132 public:
VideoProcessListener(const std::weak_ptr<VideoProcessResult> & processResult)133     explicit VideoProcessListener(const std::weak_ptr<VideoProcessResult>& processResult)
134         : processResult_(processResult)
135     {
136         DP_DEBUG_LOG("entered.");
137     }
138 
139     // LCOV_EXCL_START
OnProcessDone(const std::string & videoId)140     int32_t OnProcessDone(const std::string& videoId) override
141     {
142         DP_INFO_LOG("DPS_VIDEO: videoId: %{public}s", videoId.c_str());
143         auto processResult = processResult_.lock();
144         DP_CHECK_ERROR_RETURN_RET_LOG(processResult == nullptr, DP_OK, "VideoProcessResult is nullptr.");
145 
146         processResult->OnProcessDone(videoId);
147         return DP_OK;
148     }
149 
OnProcessDone(const std::string & videoId,const sptr<HDI::Camera::V1_0::MapDataSequenceable> & metaData)150     int32_t OnProcessDone(const std::string& videoId,
151         const sptr<HDI::Camera::V1_0::MapDataSequenceable>& metaData) override
152     {
153         DP_INFO_LOG("DPS_VIDEO: videoId: %{public}s", videoId.c_str());
154         auto processResult = processResult_.lock();
155         DP_CHECK_ERROR_RETURN_RET_LOG(processResult == nullptr, DP_OK, "VideoProcessResult is nullptr.");
156 
157         auto ret = processResult->ProcessVideoInfo(videoId, metaData);
158         if (ret != DP_OK) {
159             DP_ERR_LOG("process done failed videoId: %{public}s.", videoId.c_str());
160             processResult->OnError(videoId, DPS_ERROR_IMAGE_PROC_FAILED);
161         }
162         return DP_OK;
163     }
164 
OnError(const std::string & videoId,OHOS::HDI::Camera::V1_2::ErrorCode errorCode)165     int32_t OnError(const std::string& videoId, OHOS::HDI::Camera::V1_2::ErrorCode errorCode) override
166     {
167         DP_INFO_LOG("DPS_VIDEO: videoId: %{public}s, error: %{public}d", videoId.c_str(), errorCode);
168         auto processResult = processResult_.lock();
169         DP_CHECK_ERROR_RETURN_RET_LOG(processResult == nullptr, DP_OK, "VideoProcessResult is nullptr.");
170 
171         processResult->OnError(videoId, MapHdiVideoError(errorCode));
172         return DP_OK;
173     }
174 
OnStatusChanged(OHOS::HDI::Camera::V1_2::SessionStatus status)175     int32_t OnStatusChanged(OHOS::HDI::Camera::V1_2::SessionStatus status) override
176     {
177         DP_INFO_LOG("DPS_VIDEO: HdiStatus: %{public}d", status);
178         auto processResult = processResult_.lock();
179         DP_CHECK_ERROR_RETURN_RET_LOG(processResult == nullptr, DP_OK, "VideoProcessResult is nullptr.");
180 
181         processResult->OnStateChanged(MapHdiVideoStatus(status));
182         return DP_OK;
183     }
184     // LCOV_EXCL_STOP
185 
186 private:
187     std::weak_ptr<VideoProcessResult> processResult_;
188 };
189 
VideoPostProcessor(const int32_t userId)190 VideoPostProcessor::VideoPostProcessor(const int32_t userId)
191     : userId_(userId), serviceListener_(nullptr), sessionDeathRecipient_(nullptr), processListener_(nullptr)
192 {
193     DP_DEBUG_LOG("entered");
194 }
195 
~VideoPostProcessor()196 VideoPostProcessor::~VideoPostProcessor()
197 {
198     DP_DEBUG_LOG("entered");
199     DisconnectService();
200     SetVideoSession(nullptr);
201     allStreamInfo_.clear();
202     runningWork_.clear();
203 }
204 
Initialize()205 void VideoPostProcessor::Initialize()
206 {
207     DP_DEBUG_LOG("entered");
208     processResult_ = std::make_shared<VideoProcessResult>(userId_);
209     sessionDeathRecipient_ = sptr<SessionDeathRecipient>::MakeSptr(processResult_);
210     processListener_ = sptr<VideoProcessListener>::MakeSptr(processResult_);
211     ConnectService();
212 }
213 
GetPendingVideos(std::vector<std::string> & pendingVideos)214 bool VideoPostProcessor::GetPendingVideos(std::vector<std::string>& pendingVideos)
215 {
216     auto session = GetVideoSession();
217     DP_CHECK_ERROR_RETURN_RET_LOG(session == nullptr, false, "video session is nullptr.");
218     int32_t ret = session->GetPendingVideos(pendingVideos);
219     DP_INFO_LOG("DPS_VIDEO: GetPendingVideos size: %{public}d, ret: %{public}d",
220         static_cast<int32_t>(pendingVideos.size()), ret);
221     return ret == DP_OK;
222 }
223 
SetExecutionMode(ExecutionMode executionMode)224 void VideoPostProcessor::SetExecutionMode(ExecutionMode executionMode)
225 {
226     DP_DEBUG_LOG("entered.");
227 }
228 
SetDefaultExecutionMode()229 void VideoPostProcessor::SetDefaultExecutionMode()
230 {
231     DP_DEBUG_LOG("entered.");
232 }
233 
ProcessRequest(const DeferredVideoWorkPtr & work)234 void VideoPostProcessor::ProcessRequest(const DeferredVideoWorkPtr& work)
235 {
236     auto session = GetVideoSession();
237     auto videoId = work->GetDeferredVideoJob()->GetVideoId();
238     StartTimer(videoId, work);
239     if (session == nullptr) {
240         DP_ERR_LOG("Process videoId: %{public}s failed, video session is nullptr", videoId.c_str());
241         DP_CHECK_EXECUTE(processResult_, processResult_->OnError(videoId, DPS_ERROR_SESSION_NOT_READY_TEMPORARILY));
242         return;
243     }
244 
245     auto inFd = work->GetDeferredVideoJob()->GetInputFd();
246     if (!StartMpeg(videoId, inFd)) {
247         DP_CHECK_EXECUTE(processResult_, processResult_->OnError(videoId, DPS_ERROR_VIDEO_PROC_FAILED));
248         return;
249     }
250 
251     auto error = PrepareStreams(videoId, inFd->GetFd());
252     if (error != DPS_NO_ERROR) {
253         DP_CHECK_EXECUTE(processResult_, processResult_->OnError(videoId, error));
254         return;
255     }
256     DP_CHECK_ERROR_RETURN_LOG(mediaManagerProxy_ == nullptr, "MediaManager is nullptr.");
257     auto startTime = mediaManagerProxy_->MpegGetProcessTimeStamp();
258     auto ret = session->ProcessVideo(videoId, startTime);
259     DP_INFO_LOG("DPS_VIDEO: ProcessVideo to ive, videoId: %{public}s, startTime: %{public}" PRIu64 ", ret: %{public}d",
260         videoId.c_str(), startTime, ret);
261 }
262 
RemoveRequest(const std::string & videoId)263 void VideoPostProcessor::RemoveRequest(const std::string& videoId)
264 {
265     auto session = GetVideoSession();
266     DP_CHECK_ERROR_RETURN_LOG(session == nullptr,
267         "failed to remove videoId: %{public}s, video session is nullptr.", videoId.c_str());
268     std::string path = PATH + videoId + OUT_TAG;
269     DP_CHECK_ERROR_PRINT_LOG(remove(path.c_str()) != 0, "Failed to remove file at path: %{public}s", path.c_str());
270     auto ret = session->RemoveVideo(videoId);
271     DP_INFO_LOG("DPS_VIDEO: RemoveVideo to ive, videoId: %{public}s, ret: %{public}d", videoId.c_str(), ret);
272 }
273 
PauseRequest(const std::string & videoId,const SchedulerType & type)274 void VideoPostProcessor::PauseRequest(const std::string& videoId, const SchedulerType& type)
275 {
276     auto session = GetVideoSession();
277     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "video session is nullptr.");
278 
279     int32_t ret = session->Interrupt();
280     DP_INFO_LOG("DPS_VIDEO: Interrupt video to ive, videoId: %{public}s, ret: %{public}d", videoId.c_str(), ret);
281 }
282 
PrepareStreams(const std::string & videoId,const int inputFd)283 DpsError VideoPostProcessor::PrepareStreams(const std::string& videoId, const int inputFd)
284 {
285     auto session = GetVideoSession();
286     DP_CHECK_ERROR_RETURN_RET_LOG(session == nullptr, DPS_ERROR_VIDEO_PROC_FAILED, "video session is nullptr.");
287     // LCOV_EXCL_START
288 
289     allStreamInfo_.clear();
290     std::vector<StreamDescription> streamDescs;
291     auto ret = session->Prepare(videoId, inputFd, streamDescs);
292     DP_INFO_LOG("DPS_VIDEO: Prepare videoId: %{public}s, stream size: %{public}zu, ret: %{public}d",
293         videoId.c_str(), streamDescs.size(), ret);
294 
295     for (const auto& stream : streamDescs) {
296         DP_LOOP_ERROR_RETURN_RET_LOG(!ProcessStream(stream), DPS_ERROR_VIDEO_PROC_FAILED,
297             "ProcessStream failed streamType: %{public}d", stream.type);
298     }
299     DP_CHECK_ERROR_RETURN_RET_LOG(allStreamInfo_.empty(), DPS_ERROR_VIDEO_PROC_FAILED, "allStreamInfo is null.");
300 
301     if (EventsInfo::GetInstance().IsCameraOpen()) {
302         allStreamInfo_.clear();
303         return DPS_ERROR_VIDEO_PROC_INTERRUPTED;
304     }
305     ret = session->CreateStreams(allStreamInfo_);
306     DP_INFO_LOG("DPS_VIDEO: CreateStreams videoId: %{public}s, ret: %{public}d", videoId.c_str(), ret);
307 
308     std::vector<uint8_t> modeSetting;
309     ret = session->CommitStreams(modeSetting);
310     DP_INFO_LOG("DPS_VIDEO: CommitStreams videoId: %{public}s, ret: %{public}d", videoId.c_str(), ret);
311     return DPS_NO_ERROR;
312     // LCOV_EXCL_STOP
313 }
314 
315 // LCOV_EXCL_START
ProcessStream(const StreamDescription & stream)316 bool VideoPostProcessor::ProcessStream(const StreamDescription& stream)
317 {
318     DP_CHECK_ERROR_RETURN_RET_LOG(mediaManagerProxy_ == nullptr, false, "MediaManager is nullptr.");
319     DP_INFO_LOG("DPS_VIDEO: streamId: %{public}d, stream type: %{public}d", stream.streamId, stream.type);
320     sptr<Surface> surface = nullptr;
321     if (stream.type == HDI::Camera::V1_3::MEDIA_STREAM_TYPE_VIDEO) {
322         surface = mediaManagerProxy_->MpegGetSurface();
323     } else if (stream.type == HDI::Camera::V1_3::MEDIA_STREAM_TYPE_MAKER) {
324         surface = mediaManagerProxy_->MpegGetMakerSurface();
325         DP_CHECK_EXECUTE(mediaManagerProxy_, mediaManagerProxy_->MpegSetMarkSize(stream.width * stream.height));
326     }
327     DP_CHECK_ERROR_RETURN_RET_LOG(surface == nullptr, false, "Surface is nullptr.");
328 
329     auto producer = sptr<BufferProducerSequenceable>::MakeSptr(surface->GetProducer());
330     DP_CHECK_ERROR_RETURN_RET_LOG(producer == nullptr, false, "BufferProducer is nullptr.");
331 
332     SetStreamInfo(stream, producer);
333     return true;
334 }
335 // LCOV_EXCL_STOP
336 
ReleaseStreams()337 void VideoPostProcessor::ReleaseStreams()
338 {
339     DP_CHECK_RETURN(allStreamInfo_.empty());
340 
341     auto session = GetVideoSession();
342     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "Release streams failed, video session is nullptr.");
343 
344     auto ret = session->ReleaseStreams(allStreamInfo_);
345     allStreamInfo_.clear();
346     DP_INFO_LOG("DPS_VIDEO: ReleaseStreams ret: %{public}d", ret);
347 }
348 
SetStreamInfo(const StreamDescription & stream,sptr<BufferProducerSequenceable> & producer)349 void VideoPostProcessor::SetStreamInfo(const StreamDescription& stream, sptr<BufferProducerSequenceable>& producer)
350 {
351     StreamInfo_V1_1 streamInfo;
352     streamInfo.v1_0.intent_ = GetIntent(stream.type);
353     streamInfo.v1_0.tunneledMode_ = true;
354     streamInfo.v1_0.streamId_ = stream.streamId;
355     streamInfo.v1_0.width_ = stream.width;
356     streamInfo.v1_0.height_ = stream.height;
357     streamInfo.v1_0.format_ = stream.pixelFormat;
358     streamInfo.v1_0.dataspace_ = stream.dataspace;
359     streamInfo.v1_0.bufferQueue_ = producer;
360     allStreamInfo_.emplace_back(streamInfo);
361 }
362 
GetIntent(HDI::Camera::V1_3::MediaStreamType type)363 HDI::Camera::V1_0::StreamIntent VideoPostProcessor::GetIntent(HDI::Camera::V1_3::MediaStreamType type)
364 {
365     HDI::Camera::V1_0::StreamIntent intent = HDI::Camera::V1_0::PREVIEW;
366     switch (type) {
367         case HDI::Camera::V1_3::MEDIA_STREAM_TYPE_MAKER:
368             intent = HDI::Camera::V1_0::CUSTOM;
369             break;
370         case HDI::Camera::V1_3::MEDIA_STREAM_TYPE_VIDEO:
371             intent = HDI::Camera::V1_0::VIDEO;
372             break;
373         default:
374             DP_ERR_LOG("unexpected error type: %{public}d.", type);
375             break;
376     }
377     return intent;
378 }
379 
StartMpeg(const std::string & videoId,const sptr<IPCFileDescriptor> & inputFd)380 bool VideoPostProcessor::StartMpeg(const std::string& videoId, const sptr<IPCFileDescriptor>& inputFd)
381 {
382     DP_CHECK_EXECUTE(mediaManagerProxy_ == nullptr,
383         mediaManagerProxy_ = MediaManagerProxy::CreateMediaManagerProxy());
384     DP_CHECK_ERROR_RETURN_RET_LOG(mediaManagerProxy_ == nullptr, false, "MediaManagerProxy is nullptr.");
385     int32_t ret = mediaManagerProxy_->MpegAcquire(videoId, inputFd);
386     DP_CHECK_ERROR_RETURN_RET_LOG(ret != DP_OK, false, "MpegAcquire failed");
387     DP_DEBUG_LOG("DPS_VIDEO: Acquire MpegManager.");
388     return true;
389 }
390 
StopMpeg(const MediaResult result,const DeferredVideoWorkPtr & work)391 bool VideoPostProcessor::StopMpeg(const MediaResult result, const DeferredVideoWorkPtr& work)
392 {
393     DP_CHECK_ERROR_RETURN_RET_LOG(mediaManagerProxy_ == nullptr, false, "mpegManager is nullptr");
394     // LCOV_EXCL_START
395     mediaManagerProxy_->MpegUnInit(static_cast<int32_t>(result));
396     if (result != MediaResult::SUCCESS) {
397         ReleaseMpeg();
398         return true;
399     }
400 
401     auto videoId = work->GetDeferredVideoJob()->GetVideoId();
402     auto resultFd = mediaManagerProxy_->MpegGetResultFd();
403     DP_CHECK_ERROR_RETURN_RET_LOG(resultFd == nullptr, false,
404         "Get video fd failed, videoId: %{public}s", videoId.c_str());
405 
406     auto tempFd = resultFd->GetFd();
407     auto outFd = work->GetDeferredVideoJob()->GetOutputFd()->GetFd();
408     DP_INFO_LOG("DPS_VIDEO: Video process done, videoId: %{public}s, tempFd: %{public}d, outFd: %{public}d",
409         videoId.c_str(), tempFd, outFd);
410     copyFileByFd(tempFd, outFd);
411     DP_CHECK_ERROR_RETURN_RET_LOG(IsFileEmpty(outFd), false,
412         "Video size is empty, videoId: %{public}s", videoId.c_str());
413 
414     ReleaseMpeg();
415     return true;
416     // LCOV_EXCL_STOP
417 }
418 
419 // LCOV_EXCL_START
ReleaseMpeg()420 void VideoPostProcessor::ReleaseMpeg()
421 {
422     DP_CHECK_ERROR_RETURN_LOG(mediaManagerProxy_ == nullptr, "mpegManager is nullptr");
423     mediaManagerProxy_->MpegRelease();
424     mediaManagerProxy_.reset();
425     DP_INFO_LOG("DPS_VIDEO: Release MpegManager.");
426 }
427 // LCOV_EXCL_STOP
428 
StartTimer(const std::string & videoId,const DeferredVideoWorkPtr & work)429 void VideoPostProcessor::StartTimer(const std::string& videoId, const DeferredVideoWorkPtr& work)
430 {
431     uint32_t timeId = DpsTimer::GetInstance().StartTimer([&, videoId]() {OnTimerOut(videoId);}, MAX_PROC_TIME_MS);
432     work->SetTimeId(timeId);
433     DP_INFO_LOG("DpsTimer start, videoId: %{public}s, timeId: %{public}u", videoId.c_str(), timeId);
434     runningWork_.emplace(videoId, work);
435 }
436 
StopTimer(const DeferredVideoWorkPtr & work)437 void VideoPostProcessor::StopTimer(const DeferredVideoWorkPtr& work)
438 {
439     DP_CHECK_RETURN(work == nullptr);
440     auto videoId = work->GetDeferredVideoJob()->GetVideoId();
441     runningWork_.erase(videoId);
442     auto timeId = work->GetTimeId();
443     DP_INFO_LOG("DpsTimer stop, videoId: %{public}s, timeId: %{public}u", videoId.c_str(), timeId);
444     DpsTimer::GetInstance().StopTimer(timeId);
445 }
446 
GetRunningWork(const std::string & videoId)447 DeferredVideoWorkPtr VideoPostProcessor::GetRunningWork(const std::string& videoId)
448 {
449     auto it = runningWork_.find(videoId);
450     DP_CHECK_ERROR_RETURN_RET_LOG(it == runningWork_.end(), nullptr,
451         "GetRunningWork not found for videoId: %{public}s", videoId.c_str());
452     return it->second;
453 }
454 
OnSessionDied()455 void VideoPostProcessor::OnSessionDied()
456 {
457     SetVideoSession(nullptr);
458     std::vector<std::string> crashJobs;
459     for (const auto& item : runningWork_) {
460         crashJobs.emplace_back(item.first);
461     }
462     for (const auto& videoId : crashJobs) {
463         DP_CHECK_EXECUTE(processResult_, processResult_->OnError(videoId, DPS_ERROR_VIDEO_PROC_INTERRUPTED));
464     }
465     crashJobs.clear();
466     OnStateChanged(HdiStatus::HDI_DISCONNECTED);
467 }
468 
OnProcessDone(const std::string & videoId,std::unique_ptr<MediaUserInfo> userInfo)469 void VideoPostProcessor::OnProcessDone(const std::string& videoId, std::unique_ptr<MediaUserInfo> userInfo)
470 {
471     ReleaseStreams();
472     auto work = GetRunningWork(videoId);
473     DP_CHECK_ERROR_RETURN_LOG(work == nullptr, "video work is nullptr.");
474     // LCOV_EXCL_START
475     if (userInfo) {
476         DP_CHECK_EXECUTE(mediaManagerProxy_, mediaManagerProxy_->MpegAddUserMeta(std::move(userInfo)));
477     }
478     auto ret = StopMpeg(MediaResult::SUCCESS, work);
479     if (!ret) {
480         DP_CHECK_EXECUTE(processResult_, processResult_->OnError(videoId, DPS_ERROR_VIDEO_PROC_FAILED));
481         return;
482     }
483 
484     DP_INFO_LOG("DPS_VIDEO: video process done, videoId: %{public}s", videoId.c_str());
485     StopTimer(work);
486     if (auto schedulerManager = DPS_GetSchedulerManager()) {
487         if (auto videoController = schedulerManager->GetVideoController(userId_)) {
488             videoController->HandleSuccess(work);
489         }
490     }
491     // LCOV_EXCL_STOP
492 }
493 
OnError(const std::string & videoId,DpsError errorCode)494 void VideoPostProcessor::OnError(const std::string& videoId, DpsError errorCode)
495 {
496     ReleaseStreams();
497     auto work = GetRunningWork(videoId);
498     DP_CHECK_ERROR_RETURN_LOG(work == nullptr, "video work is nullptr.");
499     MediaResult resule = errorCode == DPS_ERROR_VIDEO_PROC_INTERRUPTED ? MediaResult::PAUSE : MediaResult::FAIL;
500     StopMpeg(resule, work);
501 
502     DP_INFO_LOG("DPS_VIDEO: video process error, videoId: %{public}s, error: %{public}d",
503         work->GetDeferredVideoJob()->GetVideoId().c_str(), errorCode);
504     StopTimer(work);
505     if (auto schedulerManager = DPS_GetSchedulerManager()) {
506         if (auto videoController = schedulerManager->GetVideoController(userId_)) {
507             videoController->HandleError(work, errorCode);
508         }
509     }
510 }
511 
OnStateChanged(HdiStatus hdiStatus)512 void VideoPostProcessor::OnStateChanged(HdiStatus hdiStatus)
513 {
514     EventsMonitor::GetInstance().NotifyVideoEnhanceStatus(hdiStatus);
515 }
516 
OnTimerOut(const std::string & videoId)517 void VideoPostProcessor::OnTimerOut(const std::string& videoId)
518 {
519     DP_INFO_LOG("DpsTimer end, videoId: %{public}s", videoId.c_str());
520     DP_CHECK_EXECUTE(processResult_, processResult_->OnError(videoId, DPS_ERROR_VIDEO_PROC_TIMEOUT));
521 }
522 
ConnectService()523 void VideoPostProcessor::ConnectService()
524 {
525     auto svcMgr = HDI::ServiceManager::V1_0::IServiceManager::Get();
526     DP_CHECK_ERROR_RETURN_LOG(svcMgr == nullptr, "IServiceManager init failed.");
527 
528     serviceListener_ = sptr<VideoServiceListener>::MakeSptr(weak_from_this());
529     auto ret  = svcMgr->RegisterServiceStatusListener(serviceListener_, DEVICE_CLASS_DEFAULT);
530     DP_CHECK_ERROR_RETURN_LOG(ret != 0, "Register Video ServiceStatusListener failed.");
531 }
532 
DisconnectService()533 void VideoPostProcessor::DisconnectService()
534 {
535     auto session = GetVideoSession();
536     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "video session is nullptr.");
537 
538     const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<IVideoProcessSession>(session);
539     bool result = remote->RemoveDeathRecipient(sessionDeathRecipient_);
540     DP_CHECK_ERROR_RETURN_LOG(!result, "remove DeathRecipient for VideoProcessSession failed.");
541 
542     auto svcMgr = HDI::ServiceManager::V1_0::IServiceManager::Get();
543     DP_CHECK_ERROR_RETURN_LOG(svcMgr == nullptr, "IServiceManager init failed.");
544 
545     auto ret  = svcMgr->UnregisterServiceStatusListener(serviceListener_);
546     DP_CHECK_ERROR_RETURN_LOG(ret != 0, "Unregister Video ServiceStatusListener failed.");
547 }
548 
OnServiceChange(const HDI::ServiceManager::V1_0::ServiceStatus & status)549 void VideoPostProcessor::OnServiceChange(const HDI::ServiceManager::V1_0::ServiceStatus& status)
550 {
551     DP_CHECK_RETURN(status.serviceName != VIDEO_SERVICE_NAME);
552     DP_CHECK_RETURN_LOG(status.status != HDI::ServiceManager::V1_0::SERVIE_STATUS_START,
553         "video service state: %{public}d", status.status);
554     DP_CHECK_RETURN(GetVideoSession() != nullptr);
555 
556     auto proxyV1_3 = HDI::Camera::V1_3::IVideoProcessService::Get(status.serviceName);
557     DP_CHECK_ERROR_RETURN_LOG(proxyV1_3 == nullptr, "get VideoProcessService failed.");
558 
559     uint32_t majorVer = 0;
560     uint32_t minorVer = 0;
561     proxyV1_3->GetVersion(majorVer, minorVer);
562     int32_t versionId = GetVersionId(majorVer, minorVer);
563     sptr<IVideoProcessSession> session = nullptr;
564     sptr<HDI::Camera::V1_4::IVideoProcessService> proxyV1_4 = nullptr;
565     // LCOV_EXCL_START
566     if (versionId >= HDI_VERSION_ID_1_4) {
567         proxyV1_4 = HDI::Camera::V1_4::IVideoProcessService::CastFrom(proxyV1_3);
568     }
569     if (proxyV1_4 != nullptr) {
570         DP_INFO_LOG("CreateVideoProcessSession_V1_4 version=%{public}d_%{public}d", majorVer, minorVer);
571         proxyV1_4->CreateVideoProcessSession_V1_4(userId_, processListener_, session);
572     } else if (proxyV1_3 != nullptr) {
573         DP_INFO_LOG("CreateVideoProcessSession version=%{public}d_%{public}d", majorVer, minorVer);
574         proxyV1_3->CreateVideoProcessSession(userId_, processListener_, session);
575     }
576     // LCOV_EXCL_STOP
577     DP_CHECK_ERROR_RETURN_LOG(session == nullptr, "get VideoProcessSession failed.");
578 
579     const sptr<IRemoteObject>& remote = HDI::hdi_objcast<IVideoProcessSession>(session);
580     bool result = remote->AddDeathRecipient(sessionDeathRecipient_);
581     DP_CHECK_ERROR_RETURN_LOG(!result, "add DeathRecipient for VideoProcessSession failed.");
582 
583     SetVideoSession(session);
584     OnStateChanged(HdiStatus::HDI_READY);
585 }
586 
copyFileByFd(const int srcFd,const int dstFd)587 void VideoPostProcessor::copyFileByFd(const int srcFd, const int dstFd)
588 {
589     struct stat buffer;
590     DP_CHECK_ERROR_RETURN_LOG(fstat(srcFd, &buffer) == -1,
591         "get out fd status failed, err: %{public}s", std::strerror(errno));
592 
593     off_t offset = 0;
594     ssize_t bytesSent;
595     while (offset < buffer.st_size) {
596         bytesSent = sendfile(dstFd, srcFd, &offset, buffer.st_size - offset);
597         DP_CHECK_ERROR_RETURN_LOG(bytesSent == -1, "copy file failed, err: %{public}s", std::strerror(errno));
598     }
599 }
600 } // namespace DeferredProcessing
601 } // namespace CameraStandard
602 } // namespace OHOS