/* * Copyright (c) 2023 Fancy Code. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "MediaHandle.h" #include "IHalCpp.h" #include "ILog.h" #include "IMediaManager.h" #include "RecordMp4.h" #include "StatusCode.h" #include #include #include #include #include #include MediaHandle::MediaHandle(const MediaChannel &mediaChannel, const std::shared_ptr &cameraHal) : mMediaChannel(mediaChannel), mCameraHal(cameraHal), mTaskRuning(false) { } void MediaHandle::Init(void) { if (mCameraHal == nullptr) { LogError("CameraHal is null.\n"); return; } auto audioFunc = std::bind(&MediaHandle::GetAudioStreamCallback, this, _1, _2, _3); mCameraHal->SetAudioStreamCallback(audioFunc); auto videoFunc = std::bind(&MediaHandle::GetVideoStreamCallback, this, _1, _2, _3); mCameraHal->SetVideoStreamCallback(videoFunc); } void MediaHandle::UnInit(void) { mTaskRuning = false; mCv.notify_one(); if (mTaskTimerThread.joinable()) { mTaskTimerThread.join(); } if (mCameraHal) { /** * @brief Before releasing the class instance, it is necessary to call the UnInit function to ensure that the * callback function is cleared elsewhere, otherwise it will crash. */ mCameraHal->SetAudioStreamCallback(nullptr); mCameraHal->SetVideoStreamCallback(nullptr); } } StatusCode MediaHandle::ExecuteTask(std::shared_ptr &task) { std::lock_guard locker(mMutex); LogInfo("CameraHandle::ExecuteTask.\n"); auto runingTask = mCurrentTask.lock(); if (!mCurrentTask.expired()) { if (!runingTask->IsTaskFinished()) { LogError("Camera is runing task, can't execute more task.\n"); return CreateStatusCode(STATUS_CODE_NOT_OK); } } mStreamHandle = std::make_shared(); if (nullptr == mStreamHandle) { LogError("Create stream handle failed.\n"); return CreateStatusCode(STATUS_CODE_NOT_OK); } mStreamHandle->Init(); CameraTaskType taskType = TaskTypeConvert(task->GetTaskType()); CameraTaskParam data(taskType); auto code = mCameraHal->StartSingleTask(data); if (IsCodeOK(code)) { mCurrentTask = task; StartTaskTimer(); } else { LogError("Execute task failed.\n"); } return code; } StatusCode MediaHandle::StopTask(void) { return CreateStatusCode(STATUS_CODE_OK); } StatusCode MediaHandle::ClearTask(void) { return CreateStatusCode(STATUS_CODE_OK); } void MediaHandle::StartTaskTimer(void) { auto taskTimerThread = [=](std::shared_ptr media) { LogInfo("StartTaskTimer start.\n"); media->TaskTimer(); }; std::shared_ptr media = shared_from_this(); mTaskTimerThread = std::thread(taskTimerThread, media); } void MediaHandle::TaskTimer(void) { constexpr int TASK_TIMER = 1000 * 10; mTaskRuning = true; while (mTaskRuning) { std::unique_lock lock(mMutex); mCv.wait_for(lock, std::chrono::milliseconds(TASK_TIMER), [&] { return !mTaskRuning; }); /** * @brief If the recording time is over, you need to stop the recording timer here. */ mTaskRuning = false; } mStreamHandle->UnInit(); if (mCameraHal) { mCameraHal->StopTask(); } mMutex.lock(); auto runingTask = mCurrentTask.lock(); if (mCurrentTask.expired()) { LogWarning("SdCardHal: monitor is expired.\n"); return; } LogInfo("Task finished response to application.\n"); std::vector responses; runingTask->Response(responses); mCurrentTask.reset(); mMutex.unlock(); } CameraTaskType MediaHandle::TaskTypeConvert(const MediaTaskType &type) { return CameraTaskType::END; } void MediaHandle::GetVideoStreamCallback(const void *stream, const int &length, const unsigned long long &timeStamp) { mStreamHandle->GetVideoStream(stream, length, timeStamp); } void MediaHandle::GetAudioStreamCallback(const void *stream, const int &length, const unsigned long long &timeStamp) { mStreamHandle->GetAudioStream(stream, length, timeStamp); }