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