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