Improve:MediaManager.

This commit is contained in:
Fancy code 2024-06-14 20:03:14 +08:00
parent a20ed62c08
commit 113275600c
13 changed files with 284 additions and 60 deletions

View File

@ -64,6 +64,11 @@ void VCameraHalMonitor::ReportEvent(const CameraReportEvent &event)
{
LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n");
}
StatusCode VCameraTaskContext::TaskFinished(void)
{
LogWarning("STATUS_CODE_VIRTUAL_FUNCTION.\n");
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
}
camera_task_param::camera_task_param(const CameraTaskType &cameraTask) : mCameraTask(cameraTask)
{
mVideoRecordingTimeMs = DEFAULT_VIDEO_RECORDING_TIME_MS;

View File

@ -15,6 +15,7 @@
#ifndef I_HAL_CPP_H
#define I_HAL_CPP_H
#include "StatusCode.h"
#include <functional>
#include <iostream>
#include <map>
#include <memory>
@ -99,6 +100,7 @@ class VCameraTaskContext
public:
VCameraTaskContext() = default;
virtual ~VCameraTaskContext() = default;
virtual StatusCode TaskFinished(void);
};
template <typename T>
class CameraTaskContext : public VCameraTaskContext
@ -120,8 +122,10 @@ typedef struct camera_task_param
unsigned int mVideoRecordingTimeMs;
std::shared_ptr<VCameraTaskContext> mCtx;
} CameraTaskParam;
using AudioStreamCallback = void (*)(const void *, const int);
using VideoStreamCallback = void (*)(const void *, const int);
// using AudioStreamCallback = void (*)(const void *, const int, const unsigned long long);
// using VideoStreamCallback = void (*)(const void *, const int, const unsigned long long);
using AudioStreamCallback = std::function<void(const void *, const int &, const unsigned long long &)>;
using VideoStreamCallback = std::function<void(const void *, const int &, const unsigned long long &)>;
class VCameraHal
{
public:

View File

@ -14,9 +14,7 @@
*/
#include "CameraHal.h"
#include "ILog.h"
CameraHal::CameraHal()
: mTaskRuning(false), mMediaRecordingTimeMs(NO_MEDIA_RECORDING), mAudioStreamCallback(nullptr),
mVideoStreamCallback(nullptr)
CameraHal::CameraHal() : mTaskRuning(false), mAudioStreamCallback(nullptr), mVideoStreamCallback(nullptr)
{
}
void CameraHal::Init(void)
@ -24,24 +22,15 @@ void CameraHal::Init(void)
}
void CameraHal::UnInit(void)
{
mTaskRuning = false;
mCv.notify_one();
}
StatusCode CameraHal::StartSingleTask(const CameraTaskParam &param)
{
mMediaRecordingTimeMs = param.mVideoRecordingTimeMs;
auto taskTimerThread = [=](std::shared_ptr<CameraHal> media) {
LogInfo("StartSingleTask start.\n");
media->TaskTimer();
};
std::shared_ptr<CameraHal> media = std::dynamic_pointer_cast<CameraHal>(shared_from_this());
mTaskTimerThread = std::thread(taskTimerThread, media);
mTaskRuning = true;
return CreateStatusCode(STATUS_CODE_OK);
}
StatusCode CameraHal::StopTask(void)
{
mTaskRuning = false;
mCv.notify_one();
return CreateStatusCode(STATUS_CODE_OK);
}
StatusCode CameraHal::SetAudioStreamCallback(AudioStreamCallback callback)
@ -54,43 +43,15 @@ StatusCode CameraHal::SetVideoStreamCallback(VideoStreamCallback callback)
mVideoStreamCallback = callback;
return CreateStatusCode(STATUS_CODE_OK);
}
void CameraHal::GetAudioStream(const void *stream, const unsigned int &length)
void CameraHal::GetAudioStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp)
{
if (mTaskRuning && nullptr != mAudioStreamCallback) {
mAudioStreamCallback(stream, length);
mAudioStreamCallback(stream, length, timeStamp);
}
// if (mTaskRuning) {
// LogInfo("GetAudioStream length33:%d\n", length);
// FILE *file = nullptr;
// file = fopen("/tmp/audio.bin", "a+");
// if (file) {
// fwrite(stream, 1, length, file);
// fflush(file);
// }
// if (file) {
// fclose(file);
// }
// }
}
void CameraHal::GetVideoStream(const void *stream, const unsigned int &length)
void CameraHal::GetVideoStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp)
{
if (mTaskRuning && nullptr != mVideoStreamCallback) {
mVideoStreamCallback(stream, length);
}
}
void CameraHal::TaskTimer(void)
{
mTaskRuning = true;
while (mTaskRuning) {
std::unique_lock<std::mutex> lock(mMutex);
mCv.wait_for(lock, std::chrono::milliseconds(mMediaRecordingTimeMs), [&] {
return !mTaskRuning;
});
/**
* @brief If the recording time is over, you need to stop the recording timer here.
*/
mTaskRuning = false;
mVideoStreamCallback(stream, length, timeStamp);
}
}

View File

@ -15,7 +15,6 @@
#ifndef CAMERA_HAL_H
#define CAMERA_HAL_H
#include "IHalCpp.h"
#include <condition_variable>
#include <mutex>
#include <thread>
constexpr unsigned int NO_MEDIA_RECORDING = -1;
@ -34,18 +33,12 @@ protected:
StatusCode SetVideoStreamCallback(VideoStreamCallback callback) override;
protected:
void GetAudioStream(const void *stream, const unsigned int &length);
void GetVideoStream(const void *stream, const unsigned int &length);
void GetAudioStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp);
void GetVideoStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp);
private:
void TaskTimer(void);
private:
std::mutex mMutex;
std::condition_variable mCv;
// std::mutex mMutex;
bool mTaskRuning;
std::thread mTaskTimerThread;
unsigned int mMediaRecordingTimeMs;
AudioStreamCallback mAudioStreamCallback;
VideoStreamCallback mVideoStreamCallback;
};

View File

@ -14,10 +14,38 @@
*/
#include "MediaHandle.h"
#include "ILog.h"
#include "SaveStream.h"
MediaHandle::MediaHandle(const MediaChannel &mediaChannel, const std::shared_ptr<VCameraHal> &cameraHal)
: mMediaChannel(mediaChannel), mCameraHal(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::GetVideoStreamCallback, this, _1, _2, _3);
mCameraHal->SetAudioStreamCallback(audioFunc);
auto videoFunc = std::bind(&MediaHandle::GetAudioStreamCallback, 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<VMediaTask> &task)
{
std::lock_guard<std::mutex> locker(mMutex);
@ -29,11 +57,18 @@ StatusCode MediaHandle::ExecuteTask(std::shared_ptr<VMediaTask> &task)
return CreateStatusCode(STATUS_CODE_NOT_OK);
}
}
mStreamHandle = std::make_shared<SaveStream>();
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");
@ -48,7 +83,53 @@ StatusCode MediaHandle::ClearTask(void)
{
return CreateStatusCode(STATUS_CODE_OK);
}
void MediaHandle::StartTaskTimer(void)
{
auto taskTimerThread = [=](std::shared_ptr<MediaHandle> media) {
LogInfo("StartTaskTimer start.\n");
media->TaskTimer();
};
std::shared_ptr<MediaHandle> 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<std::mutex> 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;
}
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<MediaTaskResponse> 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);
}

View File

@ -16,23 +16,41 @@
#define MEDI_AHANDLE_H
#include "IHalCpp.h"
#include "IMediaManager.h"
#include "VStreamHandle.h"
#include <condition_variable>
#include <mutex>
#include <thread>
using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;
class MediaHandle : public VMediaHandle, public std::enable_shared_from_this<MediaHandle>
{
public:
MediaHandle(const MediaChannel &mediaChannel, const std::shared_ptr<VCameraHal> &cameraHal);
virtual ~MediaHandle() = default;
void Init(void);
void UnInit(void);
protected:
StatusCode ExecuteTask(std::shared_ptr<VMediaTask> &task) override;
StatusCode StopTask(void) override;
StatusCode ClearTask(void) override;
private:
void StartTaskTimer(void);
void TaskTimer(void);
CameraTaskType TaskTypeConvert(const MediaTaskType &type);
void GetVideoStreamCallback(const void *stream, const int &length, const unsigned long long &timeStamp);
void GetAudioStreamCallback(const void *stream, const int &length, const unsigned long long &timeStamp);
private:
std::mutex mMutex;
std::condition_variable mCv;
const MediaChannel &mMediaChannel;
std::shared_ptr<VCameraHal> mCameraHal;
std::weak_ptr<VMediaTask> mCurrentTask;
std::shared_ptr<VStreamHandle> mStreamHandle;
bool mTaskRuning;
std::thread mTaskTimerThread;
};
#endif

View File

@ -23,6 +23,7 @@ StatusCode MediaManagerImpl::Init(void)
}
StatusCode MediaManagerImpl::UnInit(void)
{
UnInitMediaHandles();
return CreateStatusCode(STATUS_CODE_OK);
}
StatusCode MediaManagerImpl::GetMediaChannel(const MediaChannel &channel, std::shared_ptr<VMediaHandle> &handle)
@ -76,8 +77,21 @@ void MediaManagerImpl::InitMediaHandles(std::map<CameraType, std::shared_ptr<VCa
continue;
}
MediaChannel channel = static_cast<MediaChannel>(i);
std::shared_ptr<VMediaHandle> media = std::make_shared<MediaHandle>(channel, camera->second);
std::shared_ptr<MediaHandle> media = std::make_shared<MediaHandle>(channel, camera->second);
media->Init();
mAllMediaChannels[channel] = media;
LogInfo("InitMediaHandles. channel = %d \n", static_cast<MediaChannel>(i));
}
}
void MediaManagerImpl::UnInitMediaHandles(void)
{
for (auto &media : mAllMediaChannels) {
LogInfo("UnInitMediaHandles. channel = %d \n", media.first);
std::shared_ptr<MediaHandle> mediaImpl = std::dynamic_pointer_cast<MediaHandle>(media.second);
if (nullptr == mediaImpl) {
LogWarning("mediaImpl is null.\n");
continue;
}
mediaImpl->UnInit();
}
}

View File

@ -33,6 +33,7 @@ public:
private:
void SetCamerasMonitor(std::map<CameraType, std::shared_ptr<VCameraHal>> &allCameras);
void InitMediaHandles(std::map<CameraType, std::shared_ptr<VCameraHal>> &allCameras);
void UnInitMediaHandles(void);
private:
std::map<CameraType, std::shared_ptr<VCameraHal>> mAllCameras;

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2023 Fancy Code.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this mFileAudio 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 "SaveStream.h"
SaveStream::SaveStream() : mFileAudio(nullptr), mFileVideo(nullptr)
{
}
void SaveStream::Init(void)
{
mFileAudio = fopen("/tmp/audio.g711", "a+"); // TODO:
mFileVideo = fopen("/tmp/video.h264", "a+"); // TODO:
}
void SaveStream::UnInit(void)
{
if (mFileAudio) {
fclose(mFileAudio);
mFileAudio = nullptr;
}
if (mFileVideo) {
fclose(mFileVideo);
mFileVideo = nullptr;
}
}
void SaveStream::GetVideoStream(const void *stream, const int &length, const unsigned long long &timeStamp)
{
if (mFileVideo) {
fwrite(stream, 1, length, mFileVideo);
fflush(mFileVideo);
}
}
void SaveStream::GetAudioStream(const void *stream, const int &length, const unsigned long long &timeStamp)
{
if (mFileAudio) {
fwrite(stream, 1, length, mFileAudio);
fflush(mFileAudio);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.
*/
#ifndef SAVE_STREAM_H
#define SAVE_STREAM_H
#include "VStreamHandle.h"
#include <cstdio>
class SaveStream : public VStreamHandle
{
public:
SaveStream();
virtual ~SaveStream() = default;
void Init(void) override;
void UnInit(void) override;
void GetVideoStream(const void *stream, const int &length, const unsigned long long &timeStamp) override;
void GetAudioStream(const void *stream, const int &length, const unsigned long long &timeStamp) override;
private:
FILE *mFileAudio;
FILE *mFileVideo;
};
#endif

View File

@ -0,0 +1,27 @@
/*
* 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 "VStreamHandle.h"
void VStreamHandle::Init(void)
{
}
void VStreamHandle::UnInit(void)
{
}
void VStreamHandle::GetVideoStream(const void *stream, const int &length, const unsigned long long &timeStamp)
{
}
void VStreamHandle::GetAudioStream(const void *stream, const int &length, const unsigned long long &timeStamp)
{
}

View File

@ -0,0 +1,27 @@
/*
* 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.
*/
#ifndef V_STREAM_HANDLE_H
#define V_STREAM_HANDLE_H
class VStreamHandle
{
public:
VStreamHandle() = default;
virtual ~VStreamHandle() = default;
virtual void Init(void);
virtual void UnInit(void);
virtual void GetVideoStream(const void *stream, const int &length, const unsigned long long &timeStamp);
virtual void GetAudioStream(const void *stream, const int &length, const unsigned long long &timeStamp);
};
#endif

View File

@ -32,7 +32,6 @@ TEST_F(HuntingCameraTest, INTEGRATION_HunttingCamera_EXAMPLE_MediaReprot)
MockReportCameraEvent("/tmp/test.MP4", CameraType::MAIN_CAMERA);
CreateUpgradeFile();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// McuManagerTestTool::MockMcuDeviceOpenFailed(mLinuxTest);
MainThread::GetInstance()->Init();
TestManager::ResetTimeOut(1000 * 4);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
@ -40,4 +39,17 @@ TEST_F(HuntingCameraTest, INTEGRATION_HunttingCamera_EXAMPLE_MediaReprot)
MainThread::GetInstance()->Runing();
RemoveUpgradeFile();
}
// ../output_files/test/bin/HuntingCameraTest
// --gtest_filter=HuntingCameraTest.INTEGRATION_HunttingCamera_EXAMPLE_MediaTask
TEST_F(HuntingCameraTest, INTEGRATION_HunttingCamera_EXAMPLE_MediaTask)
{
McuManagerTestTool::MockOtherSideIpcMissionReply(IpcMission::TEST);
SetAllCamerasResult(mAllCamerasMock);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
MainThread::GetInstance()->Init();
TestManager::ResetTimeOut(1000 * 15);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
HalTestTool::MockKeyClick("reset", 200); // Simulate pressing a button.
MainThread::GetInstance()->Runing();
}
} // namespace MediaManager_Mock_Test