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