diff --git a/application/HuntingCamera/src/MainThread.cpp b/application/HuntingCamera/src/MainThread.cpp index b145651..aad4b62 100644 --- a/application/HuntingCamera/src/MainThread.cpp +++ b/application/HuntingCamera/src/MainThread.cpp @@ -76,13 +76,21 @@ StatusCode MainThread::Init(void) } StatusCode MainThread::UnInit(void) { + LogInfo("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.1\n"); IMissionManager::GetInstance()->UnInit(); + LogInfo("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.2\n"); IMediaManager::GetInstance()->UnInit(); + LogInfo("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.3\n"); IIpcConfig::GetInstance()->UnInit(); + LogInfo("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.4\n"); IStorageManager::GetInstance()->UnInit(); + LogInfo("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.5\n"); IMcuManager::GetInstance()->UnInit(); + LogInfo("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.6\n"); IDeviceManager::GetInstance()->UnInit(); + LogInfo("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.7\n"); IHalCpp::GetInstance()->UnInit(); + LogInfo("uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.8\n"); DestoryAllModules(); ILogUnInit(); return CreateStatusCode(STATUS_CODE_OK); diff --git a/application/MissionManager/CMakeLists.txt b/application/MissionManager/CMakeLists.txt index 8c8f30a..ee63ff1 100644 --- a/application/MissionManager/CMakeLists.txt +++ b/application/MissionManager/CMakeLists.txt @@ -20,6 +20,7 @@ include_directories( ${MIDDLEWARE_SOURCE_PATH}/McuAskBase/include ${MIDDLEWARE_SOURCE_PATH}/HuntingUpgrade/include ${MIDDLEWARE_SOURCE_PATH}/DeviceManager/include + ${MIDDLEWARE_SOURCE_PATH}/IpcConfig/include ) #do not rely on any other library #link_directories( @@ -30,7 +31,7 @@ aux_source_directory(./src SRC_FILES) set(TARGET_NAME MissionManager) add_library(${TARGET_NAME} STATIC ${SRC_FILES}) -target_link_libraries(${TARGET_NAME} McuAskBase StateMachine MediaManager StorageManager DeviceManager HuntingUpgrade KeyControl LedControl StatusCode Log) +target_link_libraries(${TARGET_NAME} McuAskBase StateMachine MediaManager StorageManager DeviceManager HuntingUpgrade KeyControl LedControl IpcConfig StatusCode Log) add_custom_target( MissionManager_code_check diff --git a/application/MissionManager/src/MediaHandleState.cpp b/application/MissionManager/src/MediaHandleState.cpp index b0f4400..84d00f1 100644 --- a/application/MissionManager/src/MediaHandleState.cpp +++ b/application/MissionManager/src/MediaHandleState.cpp @@ -19,8 +19,8 @@ #include "IMediaManager.h" #include "IMissionManager.h" #include "IStateMachine.h" -#include "LedsHandle.h" #include "LedControl.h" +#include "LedsHandle.h" #include "MediaTask.h" #include "MediaTaskHandle.h" #include "MissionStateMachine.h" diff --git a/application/MissionManager/src/MediaTask.cpp b/application/MissionManager/src/MediaTask.cpp index ed7fe38..4a73b6b 100644 --- a/application/MissionManager/src/MediaTask.cpp +++ b/application/MissionManager/src/MediaTask.cpp @@ -39,6 +39,10 @@ unsigned int MediaTask::GetTaskTimeOutMs(void) { return MEDIA_TASK_TIMEOUT_MS; } +const MediaTaskType MediaTask::GetTaskType(void) +{ + return mType; +} std::string MediaTask::GetTargetNameForSaving(void) { if (!mTargetName.empty()) { @@ -52,10 +56,11 @@ std::string MediaTask::GetTargetNameForSaving(void) int hour = tm_now.tm_hour; int minute = tm_now.tm_min; int second = tm_now.tm_sec; - + const std::string fileType = MediaTaskType::TAKE_VIDEO == mType ? ".mp4" : ".jpeg"; std::ostringstream pathStream; pathStream << mSavePath << "xak47-" << mSerialNumber << "-" << std::setw(2) << std::setfill('0') << hour - << std::setw(2) << std::setfill('0') << minute << std::setw(2) << std::setfill('0') << second << ".mp4"; + << std::setw(2) << std::setfill('0') << minute << std::setw(2) << std::setfill('0') << second + << fileType; mTargetName = pathStream.str(); LogInfo("GetTargetNameForSaving: %s\n", pathStream.str().c_str()); return pathStream.str(); @@ -98,11 +103,12 @@ void MediaTask::Response(const std::vector &response) } std::string MediaTask::GetThumbnailNameByTargetName(const std::string &targetName) { + // const std::string fileType = MediaTaskType::TAKE_VIDEO == mType ? ".mp4" : ".jpeg"; std::string thumbnailName = targetName; size_t dot_pos = thumbnailName.find_last_of('.'); if (dot_pos != std::string::npos) { std::string extension = thumbnailName.substr(dot_pos); - if (extension == ".mp4") { + if (extension == ".mp4" || extension == ".jpeg") { thumbnailName.replace(dot_pos, extension.length(), "-thumbnail.jpeg"); LogInfo("GetThumbnailNameForSaving: %s\n", thumbnailName.c_str()); return thumbnailName; diff --git a/application/MissionManager/src/MediaTask.h b/application/MissionManager/src/MediaTask.h index 3835140..a7a4bb0 100644 --- a/application/MissionManager/src/MediaTask.h +++ b/application/MissionManager/src/MediaTask.h @@ -41,6 +41,7 @@ public: const std::string &savePath); virtual ~MediaTask() = default; virtual unsigned int GetTaskTimeOutMs(void); + const MediaTaskType GetTaskType(void) override; std::string GetTargetNameForSaving(void) override; std::string GetThumbnailNameForSaving(const std::string &targetName) override; int GetVideoDuration_ms(void) override; diff --git a/application/MissionManager/src/MediaTaskHandle.cpp b/application/MissionManager/src/MediaTaskHandle.cpp index dd6da5f..90c888e 100644 --- a/application/MissionManager/src/MediaTaskHandle.cpp +++ b/application/MissionManager/src/MediaTaskHandle.cpp @@ -15,6 +15,7 @@ #include "MediaTaskHandle.h" #include "DataProcessing.h" #include "IFilesManager.h" +#include "IIpcConfig.h" #include "ILog.h" #include "IMediaManager.h" #include "IMissionManager.h" @@ -40,8 +41,11 @@ void MediaTaskHandle::MakeSingleTask(const InternalStateEvent &bindEvent, const std::shared_ptr &iniator) { InfoToBeSaved info = IFilesManager::GetInstance()->GetInfoForSavingFiles(1); + WorkMode workMode = IIpcConfig::GetInstance()->GetWorkMode(); + MediaTaskType taskType = WorkModeConvert(workMode); + LogInfo("taskType: %s\n", IMediaManager::PrintfTaskType(taskType)); std::shared_ptr task = - std::make_shared(MediaTaskType::END, bindEvent, iniator, info.mSerialNumber, info.mSavingPath); + std::make_shared(taskType, bindEvent, iniator, info.mSerialNumber, info.mSavingPath); if (!mMediaHandle) { LogError("MediaHandle is null"); return; @@ -57,4 +61,17 @@ void MediaTaskHandle::MakeSingleTask(const InternalStateEvent &bindEvent, // else if () { // mMediaHandle->StopTask(); // } +} +MediaTaskType MediaTaskHandle::WorkModeConvert(const WorkMode &mode) +{ + switch (mode) { + case WorkMode::MODE_PIC: + return MediaTaskType::TAKE_PICTURE; + case WorkMode::MODE_PIC_VIDEO: + return MediaTaskType::TAKE_PICTURE_AND_VIDEO; + + default: + LogWarning("unknow work mode.\n"); + return MediaTaskType::TAKE_PICTURE_AND_VIDEO; + } } \ No newline at end of file diff --git a/application/MissionManager/src/MediaTaskHandle.h b/application/MissionManager/src/MediaTaskHandle.h index 4017049..07b79f2 100644 --- a/application/MissionManager/src/MediaTaskHandle.h +++ b/application/MissionManager/src/MediaTaskHandle.h @@ -15,6 +15,7 @@ #ifndef MEDIA_TASK_HANDLE_H #define MEDIA_TASK_HANDLE_H #include "DataProcessing.h" +#include "IIpcConfig.h" #include "IMediaManager.h" #include "MediaTask.h" class MediaTaskHandle @@ -26,6 +27,9 @@ public: void UnInit(void); void MakeSingleTask(const InternalStateEvent &bindEvent, const std::shared_ptr &iniator); +private: + MediaTaskType WorkModeConvert(const WorkMode &mode); + protected: std::shared_ptr mMediaHandle; diff --git a/middleware/McuManager/src/McuManagerImpl.cpp b/middleware/McuManager/src/McuManagerImpl.cpp index 1daeb96..2f0774e 100644 --- a/middleware/McuManager/src/McuManagerImpl.cpp +++ b/middleware/McuManager/src/McuManagerImpl.cpp @@ -72,14 +72,18 @@ const StatusCode McuManagerImpl::Init(void) } const StatusCode McuManagerImpl::UnInit(void) { + LogInfo("=============================== 00\n"); McuDevice::UnInit(); + LogInfo("=============================== 11\n"); McuProtocol::UnInit(); + LogInfo("=============================== 22\n"); mMcuAskList.clear(); mMonitor.reset(); mMutex.lock(); mWatchDogRuning = false; mCv.notify_one(); mMutex.unlock(); + LogInfo("=============================== 33\n"); if (mWatchDogThread.joinable()) { mWatchDogThread.join(); } @@ -202,6 +206,7 @@ void McuManagerImpl::WatchDogThread(void) mCv.wait_for(lock, std::chrono::milliseconds(WATCH_DOG_CYCLE_MS), [&] { return !mWatchDogRuning; }); + LogInfo("WatchDogThread is running.\n"); } } std::shared_ptr McuManagerImpl::GetMcuMonitor(void) diff --git a/middleware/MediaManager/include/IMediaManager.h b/middleware/MediaManager/include/IMediaManager.h index 43951ec..b06b8eb 100644 --- a/middleware/MediaManager/include/IMediaManager.h +++ b/middleware/MediaManager/include/IMediaManager.h @@ -92,5 +92,8 @@ public: virtual StatusCode UnInit(void); virtual StatusCode SetMediaMonitor(std::shared_ptr &monitor); virtual StatusCode GetMediaChannel(const MediaChannel &channel, std::shared_ptr &handle); + +public: + static const char *PrintfTaskType(const MediaTaskType &type); }; #endif \ No newline at end of file diff --git a/middleware/MediaManager/src/IMediaManager.cpp b/middleware/MediaManager/src/IMediaManager.cpp index 75ceec1..135b077 100644 --- a/middleware/MediaManager/src/IMediaManager.cpp +++ b/middleware/MediaManager/src/IMediaManager.cpp @@ -138,4 +138,19 @@ StatusCode IMediaManager::GetMediaChannel(const MediaChannel &channel, std::shar { LogWarning("STATUS_CODE_VIRTUAL_FUNCTION"); return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); +} +const char *IMediaManager::PrintfTaskType(const MediaTaskType &type) +{ + switch (type) { + case MediaTaskType::TAKE_PICTURE: + return "TAKE_PICTURE"; + case MediaTaskType::TAKE_VIDEO: + return "TAKE_VIDEO"; + case MediaTaskType::TAKE_PICTURE_AND_VIDEO: + return "TAKE_PICTURE_AND_VIDEO"; + + default: + LogWarning("unknow MediaTaskType.\n"); + return "unknow MediaTaskType"; + } } \ No newline at end of file diff --git a/middleware/MediaManager/src/MediaHandle.cpp b/middleware/MediaManager/src/MediaHandle.cpp index 4105db5..7d97757 100644 --- a/middleware/MediaManager/src/MediaHandle.cpp +++ b/middleware/MediaManager/src/MediaHandle.cpp @@ -16,7 +16,7 @@ #include "IHalCpp.h" #include "ILog.h" #include "IMediaManager.h" -#include "RecordMp4.h" +#include "MediaManagerMakePtr.h" #include "StatusCode.h" #include #include @@ -80,7 +80,8 @@ StatusCode MediaHandle::ExecuteTask(std::shared_ptr &task) return CreateStatusCode(STATUS_CODE_NOT_OK); } } - mStreamHandle = std::make_shared(task); + // mStreamHandle = std::make_shared(task); + mStreamHandle = MediaManagerMakePtr::GetInstance()->CreateMediaHandle(task); if (nullptr == mStreamHandle) { LogError("Create stream handle failed.\n"); mStreamHandle.reset(); diff --git a/middleware/MediaManager/src/MediaManagerMakePtr.cpp b/middleware/MediaManager/src/MediaManagerMakePtr.cpp index 30df0cb..5f2ebf5 100644 --- a/middleware/MediaManager/src/MediaManagerMakePtr.cpp +++ b/middleware/MediaManager/src/MediaManagerMakePtr.cpp @@ -16,7 +16,10 @@ #include "ILog.h" #include "IMediaManager.h" #include "MediaManagerImpl.h" +#include "RecordMp4.h" #include "StatusCode.h" +#include "TakePicture.h" +#include "VStreamHandle.h" #include bool CreateMediaManagerModule(void) { @@ -54,4 +57,25 @@ const StatusCode MediaManagerMakePtr::CreateMediaManagerModule(std::shared_ptr(); impl = tmp; return CreateStatusCode(STATUS_CODE_OK); +} +std::shared_ptr MediaManagerMakePtr::CreateMediaHandle(std::shared_ptr &task) +{ + const MediaTaskType type = task->GetTaskType(); + std::shared_ptr stream; + switch (type) { + case MediaTaskType::TAKE_PICTURE: + stream = std::make_shared(task); + break; + case MediaTaskType::TAKE_VIDEO: + stream = std::make_shared(task); + break; + case MediaTaskType::TAKE_PICTURE_AND_VIDEO: + /* code */ + break; + + default: + LogWarning("unsupport type.\n"); + break; + } + return stream; } \ No newline at end of file diff --git a/middleware/MediaManager/src/MediaManagerMakePtr.h b/middleware/MediaManager/src/MediaManagerMakePtr.h index 4adc017..7c7ca71 100644 --- a/middleware/MediaManager/src/MediaManagerMakePtr.h +++ b/middleware/MediaManager/src/MediaManagerMakePtr.h @@ -16,6 +16,7 @@ #define MEDIA_MANAGER_MAKE_PTR_H #include "IMediaManager.h" #include "StatusCode.h" +#include "VStreamHandle.h" #include class MediaManagerMakePtr { @@ -24,5 +25,6 @@ public: virtual ~MediaManagerMakePtr() = default; static std::shared_ptr &GetInstance(std::shared_ptr *impl = nullptr); virtual const StatusCode CreateMediaManagerModule(std::shared_ptr &impl); + virtual std::shared_ptr CreateMediaHandle(std::shared_ptr &task); }; #endif // !MEDIA_MANAGER_MAKE_PTR_H \ No newline at end of file diff --git a/middleware/MediaManager/src/TakePicture.cpp b/middleware/MediaManager/src/TakePicture.cpp new file mode 100644 index 0000000..9eb874f --- /dev/null +++ b/middleware/MediaManager/src/TakePicture.cpp @@ -0,0 +1,100 @@ +/* + * 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 "TakePicture.h" +#include "ILog.h" +#include "IMediaManager.h" +#include "MediaBase.h" +#include "StatusCode.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +TakePicture::TakePicture(std::shared_ptr &recordTask) + : mTakePictureObject(nullptr), mPictureTask(recordTask), mIsTakePictureFinished(OUTPUT_FILE_STATUS_END) +{ +} +StatusCode TakePicture::Init(void) +{ + mTakePictureObject = ICreateMediaBase(MEDIA_HANDLE_TYPE_TAKE_PICTURE); + if (nullptr == mTakePictureObject) { + LogError("mTakePictureObject is null.\n"); + return CreateStatusCode(STATUS_CODE_NOT_OK); + } + std::string picturePath = mPictureTask->GetTargetNameForSaving(); + std::string thumbnailPath = mPictureTask->GetThumbnailNameForSaving(picturePath); + OutputFileInfo fileInfo = {.mTakePicture = true, .mDuration_ms = 0, .mFinished = &mIsTakePictureFinished}; + if (OUTPUT_FILE_NAME_MAX >= picturePath.size()) { + memcpy(fileInfo.mFileName, picturePath.c_str(), picturePath.size()); + } + else { + LogError("VideoPath is too long.\n"); + return CreateStatusCode(STATUS_CODE_NOT_OK); + } + if (OUTPUT_FILE_NAME_MAX >= thumbnailPath.size()) { + memcpy(fileInfo.mThumbnailFileName, thumbnailPath.c_str(), thumbnailPath.size()); + } + else { + LogError("ThumbnailPath is too long.\n"); + return CreateStatusCode(STATUS_CODE_NOT_OK); + } + StatusCode code = IOpenJpegFile(mTakePictureObject, &fileInfo); + if (!IsCodeOK(code)) { + LogError("OpenOutputFile failed.\n"); + ICloseJpegFile(mTakePictureObject); + IMediaBaseFree(mTakePictureObject); + mTakePictureObject = nullptr; + } + return code; +} +StatusCode TakePicture::UnInit(void) +{ + StopHandleStream(); + return CreateStatusCode(STATUS_CODE_OK); +} +void TakePicture::StopHandleStream(void) +{ + std::lock_guard locker(mMutex); + if (mTakePictureObject) { + // OutputFileInfo finalFile = IGetOutputFileInfo(mTakePictureObject); + MediaTaskResponse response("finalFile.mFileName", 0); + mTaskResponse.push_back(response); + ICloseJpegFile(mTakePictureObject); + IMediaBaseFree(mTakePictureObject); + mTakePictureObject = nullptr; + } + // std::string picturePath = mPictureTask->GetTargetNameForSaving(); +} +void TakePicture::GetVideoStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp) +{ + std::lock_guard locker(mMutex); + if (mTakePictureObject) { + IWriteJpegData(mTakePictureObject, stream, length); + } +} +StatusCode TakePicture::GetAllFiles(std::vector &files) +{ + files = std::move(mTaskResponse); + mTaskResponse.clear(); + return CreateStatusCode(STATUS_CODE_OK); +} +bool TakePicture::HandleFinished(void) +{ + return mIsTakePictureFinished == OUTPUT_FILE_STATUS_FINISHED ? true : false; +} \ No newline at end of file diff --git a/middleware/MediaManager/src/TakePicture.h b/middleware/MediaManager/src/TakePicture.h new file mode 100644 index 0000000..8579112 --- /dev/null +++ b/middleware/MediaManager/src/TakePicture.h @@ -0,0 +1,41 @@ +/* + * 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 TAKE_PICTURE_H +#define TAKE_PICTURE_H +#include "IMediaManager.h" +#include "VStreamHandle.h" +#include +#include +#include +class TakePicture : public VStreamHandle +{ +public: + TakePicture(std::shared_ptr &pictureTask); + virtual ~TakePicture() = default; + StatusCode Init(void) override; + StatusCode UnInit(void) override; + void StopHandleStream(void) override; + void GetVideoStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp) override; + StatusCode GetAllFiles(std::vector &files) override; + bool HandleFinished(void) override; + +private: + std::mutex mMutex; // TODO: To improve and delete this mutex. + void *mTakePictureObject; + std::shared_ptr mPictureTask; + std::vector mTaskResponse; + int mIsTakePictureFinished; +}; +#endif \ No newline at end of file diff --git a/middleware/MediaManager/src/VStreamHandle.cpp b/middleware/MediaManager/src/VStreamHandle.cpp index c55867c..8079f7c 100644 --- a/middleware/MediaManager/src/VStreamHandle.cpp +++ b/middleware/MediaManager/src/VStreamHandle.cpp @@ -19,33 +19,33 @@ #include StatusCode VStreamHandle::Init(void) { - LogInfo("STATUS_CODE_VIRTUAL_FUNCTION\n"); + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION\n"); return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); } StatusCode VStreamHandle::UnInit(void) { - LogInfo("STATUS_CODE_VIRTUAL_FUNCTION\n"); + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION\n"); return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); } void VStreamHandle::StopHandleStream(void) { - LogInfo("STATUS_CODE_VIRTUAL_FUNCTION\n"); + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION\n"); } void VStreamHandle::GetVideoStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp) { - LogInfo("STATUS_CODE_VIRTUAL_FUNCTION\n"); + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION\n"); } void VStreamHandle::GetAudioStream(const void *stream, const unsigned int &length, const unsigned long long &timeStamp) { - LogInfo("STATUS_CODE_VIRTUAL_FUNCTION\n"); + // LogWarning("STATUS_CODE_VIRTUAL_FUNCTION\n"); } StatusCode VStreamHandle::GetAllFiles(std::vector &files) { - LogInfo("STATUS_CODE_VIRTUAL_FUNCTION\n"); + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION\n"); return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); } bool VStreamHandle::HandleFinished(void) { - LogInfo("STATUS_CODE_VIRTUAL_FUNCTION\n"); + LogWarning("STATUS_CODE_VIRTUAL_FUNCTION\n"); return false; } \ No newline at end of file diff --git a/test/application/HuntingCamera/CMakeLists.txt b/test/application/HuntingCamera/CMakeLists.txt index f0102f8..9fa6e13 100644 --- a/test/application/HuntingCamera/CMakeLists.txt +++ b/test/application/HuntingCamera/CMakeLists.txt @@ -21,6 +21,7 @@ include_directories( ${TEST_SOURCE_PATH}/middleware/McuManager/tool/include ${TEST_SOURCE_PATH}/middleware/AppManager/tool/include ${TEST_SOURCE_PATH}/middleware/DeviceManager/tool/include + ${TEST_SOURCE_PATH}/middleware/IpcConfig/tool/include ${TEST_SOURCE_PATH}/utils/LinuxApiMock/include ${TEST_SOURCE_PATH}/utils/TestManager/include ${TEST_SOURCE_PATH}/utils/McuProtocol/tool/include @@ -46,7 +47,7 @@ set(TARGET_NAME HuntingCameraTest) add_executable(${TARGET_NAME} ${SRC_FILES_MAIN} ${SRC_FILES}) target_link_libraries(${TARGET_NAME}# -Wl,--start-group HuntingMainLib MissionManagerTestTool McuManagerTestTool McuAskBaseTestTool - AppManagerTestTool HalTestTool DeviceManagerTestTool TestManager + AppManagerTestTool HalTestTool DeviceManagerTestTool IpcConfigTestTool TestManager # -Wl,--end-group gtest gmock pthread) if(${TEST_COVERAGE} MATCHES "true") diff --git a/test/application/HuntingCamera/src_mock/HuntingCameraTest.cpp b/test/application/HuntingCamera/src_mock/HuntingCameraTest.cpp index b94e24e..245196a 100644 --- a/test/application/HuntingCamera/src_mock/HuntingCameraTest.cpp +++ b/test/application/HuntingCamera/src_mock/HuntingCameraTest.cpp @@ -15,6 +15,7 @@ #include "HuntingCameraTest.h" #include "GtestUsing.h" #include "ILog.h" +#include "IpcConfigTestTool.h" #include "MainThread.h" #include const char *KEY_RESET = "reset"; @@ -55,6 +56,7 @@ void HuntingCameraTest::SetUp() LinuxApiMock::GetInstance()->Init(); McuManagerTestTool::Init(mLinuxTest); HalTestTool::InitSdCardHal(mLinuxTest); + IpcConfigTestTool::Init(mLinuxTest); DeviceManagerTestTool::Init(); TestManager::Init(); } diff --git a/test/application/HuntingCamera/src_mock/HuntingCameraTest.h b/test/application/HuntingCamera/src_mock/HuntingCameraTest.h index 2921507..04d59c6 100644 --- a/test/application/HuntingCamera/src_mock/HuntingCameraTest.h +++ b/test/application/HuntingCamera/src_mock/HuntingCameraTest.h @@ -18,6 +18,7 @@ #include "DeviceManagerTestTool.h" #include "GtestUsing.h" #include "HalTestTool.h" +#include "IpcConfigTestTool.h" #include "LinuxApiMock.h" #include "MainThread.h" #include "McuManagerTestTool.h" @@ -37,6 +38,7 @@ class HuntingCameraTest : public testing::Test, public McuManagerTestTool, public AppManagerTestTool, public DeviceManagerTestTool, + public IpcConfigTestTool, virtual public HalTestTool { public: diff --git a/test/application/HuntingCamera/src_mock/MediaManager_Mock_Test.cpp b/test/application/HuntingCamera/src_mock/MediaManager_Mock_Test.cpp index 533fd03..0df3419 100644 --- a/test/application/HuntingCamera/src_mock/MediaManager_Mock_Test.cpp +++ b/test/application/HuntingCamera/src_mock/MediaManager_Mock_Test.cpp @@ -40,6 +40,19 @@ TEST_F(HuntingCameraTest, INTEGRATION_HunttingCamera_EXAMPLE_MediaReprot) RemoveUpgradeFile(); } // ../output_files/test/bin/HuntingCameraTest +// --gtest_filter=HuntingCameraTest.INTEGRATION_HunttingCamera_EXAMPLE_TakePicture +TEST_F(HuntingCameraTest, INTEGRATION_HunttingCamera_EXAMPLE_TakePicture) +{ + McuManagerTestTool::MockOtherSideIpcMissionReply(IpcMission::TEST); + SetAllCamerasResult(mAllCamerasMock); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + MainThread::GetInstance()->Init(); + TestManager::ResetTimeOut(1000 * 5); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + HalTestTool::MockKeyClick("reset", 200); // Simulate pressing a button. + MainThread::GetInstance()->Runing(); +} +// ../output_files/test/bin/HuntingCameraTest // --gtest_filter=HuntingCameraTest.INTEGRATION_HunttingCamera_EXAMPLE_MediaTask TEST_F(HuntingCameraTest, INTEGRATION_HunttingCamera_EXAMPLE_MediaTask) { diff --git a/utils/MediaBase/include/MediaBase.h b/utils/MediaBase/include/MediaBase.h index d8a607b..5b38ef9 100644 --- a/utils/MediaBase/include/MediaBase.h +++ b/utils/MediaBase/include/MediaBase.h @@ -24,6 +24,7 @@ enum MediaHandleType MEDIA_HANDLE_TYPE_READ_H264 = 0, MEDIA_HANDLE_TYPE_READ_G711A, MEDIA_HANDLE_TYPE_COMBINE_MP4, + MEDIA_HANDLE_TYPE_TAKE_PICTURE, MEDIA_HANDLE_TYPE_END }; enum StreamType @@ -71,6 +72,12 @@ StatusCode IStopReadFile(void *object); StatusCode IOpenOutputFile(void *object, const OutputFileInfo *info); StatusCode ICloseOutputFile(void *object); void IGetStreamData(void *object, const void *data, const size_t size, const StreamInfo streamInfo); +/** + * @brief When encapsulating a video, you ultimately need to obtain the video's duration information. + * + * @param object + * @return OutputFileInfo + */ OutputFileInfo IGetOutputFileInfo(void *object); StatusCode IOpenJpegFile(void *object, const OutputFileInfo *info); diff --git a/utils/MediaBase/src/FfmpegOriginalPicture.cpp b/utils/MediaBase/src/FfmpegOriginalPicture.cpp index 74d2b77..41da91d 100644 --- a/utils/MediaBase/src/FfmpegOriginalPicture.cpp +++ b/utils/MediaBase/src/FfmpegOriginalPicture.cpp @@ -13,17 +13,34 @@ * limitations under the License. */ #include "FfmpegOriginalPicture.h" +#include "FfmpegEncoder.h" +#include "FfmpegThumbnail.h" #include "ILog.h" -original_info::original_info(const int &srouceWidth, const int &srouceHeight) - : mSrouceWidth(srouceWidth), mSrouceHeight(srouceHeight) +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include +#include +#ifdef __cplusplus +} +#endif +#include +#include +#include +#include +original_info::original_info(const int &srouceWidth, const int &srouceHeight, const std::string &thumbnail) + : mSrouceWidth(srouceWidth), mSrouceHeight(srouceHeight), mThumbnail(thumbnail) { } FfmpegOriginalPicture::FfmpegOriginalPicture(const AVCodecID &encodecId, const AVCodecID &decodecId) - : FfmpegThumbnail(encodecId, decodecId) + : FfmpegThumbnail(encodecId, decodecId), mPictureInfo(nullptr) { } void FfmpegOriginalPicture::Init(const OriginalInfo &originalInfo) { + mPictureInfo = std::make_shared(originalInfo); ThumbnailInfo thumbnailInfo(originalInfo.mSrouceWidth, originalInfo.mSrouceHeight, 192, 216); FfmpegThumbnail::Init(thumbnailInfo); } @@ -37,9 +54,8 @@ void FfmpegOriginalPicture::UnInit(void) } bool FfmpegOriginalPicture::CreateOriginalPicture(const std::string &outputFile, const void *data, const size_t &size) { - mEncodeCallback = - std::bind(&FfmpegOriginalPicture::GetEncodeDataCallback, this, std::placeholders::_1, "./test_original.jpg"); - return FfmpegThumbnail::CreateThumbnail(outputFile, data, size); + mEncodeCallback = std::bind(&FfmpegOriginalPicture::GetEncodeDataCallback, this, std::placeholders::_1, outputFile); + return FfmpegThumbnail::CreateThumbnail(mPictureInfo->mThumbnail, data, size); } void FfmpegOriginalPicture::EncodeDataToPicture(AVFrame *frame) { @@ -63,5 +79,5 @@ void FfmpegOriginalPicture::EncodeDataToPicture(AVFrame *frame) } void FfmpegOriginalPicture::GetEncodeDataCallback(AVPacket *pkt, const std::string &fileName) { - FfmpegThumbnail::SaveThumbnailFile(fileName, pkt->data, pkt->size); + FfmpegThumbnail::SavePicture(fileName, pkt->data, pkt->size); } \ No newline at end of file diff --git a/utils/MediaBase/src/FfmpegOriginalPicture.h b/utils/MediaBase/src/FfmpegOriginalPicture.h index 555ef68..9936ae3 100644 --- a/utils/MediaBase/src/FfmpegOriginalPicture.h +++ b/utils/MediaBase/src/FfmpegOriginalPicture.h @@ -36,9 +36,10 @@ extern "C" { #endif typedef struct original_info { - original_info(const int &srouceWidth, const int &srouceHeight); + original_info(const int &srouceWidth, const int &srouceHeight, const std::string &thumbnail); const int mSrouceWidth; const int mSrouceHeight; + const std::string mThumbnail; } OriginalInfo; class FfmpegOriginalPicture : public FfmpegThumbnail { @@ -56,5 +57,6 @@ private: private: std::shared_ptr mEncoder; std::function mEncodeCallback; + std::shared_ptr mPictureInfo; }; #endif \ No newline at end of file diff --git a/utils/MediaBase/src/FfmpegOutputStream.cpp b/utils/MediaBase/src/FfmpegOutputStream.cpp index 21fadd8..7b053c6 100644 --- a/utils/MediaBase/src/FfmpegOutputStream.cpp +++ b/utils/MediaBase/src/FfmpegOutputStream.cpp @@ -15,7 +15,6 @@ #include "FfmpegOutputStream.h" #include "FfmpegDecoder.h" #include "FfmpegEncoder.h" -#include "FfmpegOriginalPicture.h" #include "FfmpegThumbnail.h" #include "ILog.h" #include @@ -205,10 +204,4 @@ void FfmpegOutputStream::CreateThumbnailFileThread(const void *frame, const size thumbnail.CreateThumbnail(mThumbnailFileName, frame, size); thumbnail.UnInit(); LogInfo("CreateThumbnailFile end.\n"); - // FfmpegOriginalPicture thumbnail(AV_CODEC_ID_MJPEG, AV_CODEC_ID_H264); - // OriginalInfo info(1920, 2160); // TODO: - // thumbnail.Init(info); - // thumbnail.CreateOriginalPicture(mThumbnailFileName, frame, size); - // thumbnail.UnInit(); - // LogInfo("CreateThumbnailFile end.\n"); } \ No newline at end of file diff --git a/utils/MediaBase/src/FfmpegTakePicture.cpp b/utils/MediaBase/src/FfmpegTakePicture.cpp index 69e891e..2bacf39 100644 --- a/utils/MediaBase/src/FfmpegTakePicture.cpp +++ b/utils/MediaBase/src/FfmpegTakePicture.cpp @@ -13,31 +13,85 @@ * limitations under the License. */ #include "FfmpegTakePicture.h" +#include "FfmpegBase.h" #include "FfmpegOriginalPicture.h" #include "ILog.h" +#include "MediaBase.h" +#include "StatusCode.h" +#include +#ifdef __cplusplus +extern "C" { +#endif +#include +#ifdef __cplusplus +} +#endif +#include +#include +#include +FfmpegTakePicture::FfmpegTakePicture() : mOutputFileInfo(nullptr), mTaskRuning(false), mFrameData(nullptr) +{ +} StatusCode FfmpegTakePicture::OpenJpegFile(const OutputFileInfo &fileInfo) { - return CreateStatusCode(STATUS_CODE_OK); + mOutputFileInfo = std::make_shared(fileInfo); + if (mOutputFileInfo) { + return CreateStatusCode(STATUS_CODE_OK); + } + return CreateStatusCode(STATUS_CODE_NOT_OK); } StatusCode FfmpegTakePicture::CloseJpegFile(void) { + if (mCodecThread.joinable()) { + mCodecThread.join(); + } + if (mFrameData) { + free(mFrameData); + mFrameData = nullptr; + } return CreateStatusCode(STATUS_CODE_OK); } StatusCode FfmpegTakePicture::WriteJpegData(const void *data, const size_t &size) { + if (!mOutputFileInfo) { + LogError("mOutputFileInfoCit is null\n"); + return CreateStatusCode(STATUS_CODE_NOT_OK); + } char *pData = (char *)data; for (size_t i = 0; i < size; i++) { if ((0x00 == pData[i]) && (0x00 == pData[i + 1]) && (0x00 == pData[i + 2]) && (0x01 == pData[i + 3]) && (0x5 == (pData[i + 4] & 0x1F))) { LogInfo("Found extradata\n"); - FfmpegOriginalPicture picture(AV_CODEC_ID_MJPEG, AV_CODEC_ID_H264); - OriginalInfo info(1920, 2160); // TODO: - picture.Init(info); - picture.CreateOriginalPicture("mThumbnailFileName", data, size); - picture.UnInit(); - LogInfo("CreateThumbnailFile end.\n"); + CreateJpegFile(data, size); + if (mOutputFileInfo->mFinished) { + *(mOutputFileInfo->mFinished) = static_cast(OUTPUT_FILE_STATUS_FINISHED); + } return CreateStatusCode(STATUS_CODE_OK); } } return CreateStatusCode(STATUS_CODE_NOT_OK); +} +void inline FfmpegTakePicture::CreateJpegFile(const void *data, const size_t &size) +{ + mFrameData = (char *)malloc(size); + if (!mFrameData) { + LogError("malloc failed\n"); + return; + } + memcpy(mFrameData, data, size); + auto codecThread = [](std::shared_ptr output, const void *frameData, const size_t dataSize) { + LogInfo("CreateJpegFile start.\n"); + output->CreateJpegFileThread(frameData, dataSize); + }; + std::shared_ptr impl = + std::dynamic_pointer_cast(FfmpegBase::shared_from_this()); + mCodecThread = std::thread(codecThread, impl, mFrameData, size); +} +void FfmpegTakePicture::CreateJpegFileThread(const void *data, const size_t &size) +{ + FfmpegOriginalPicture picture(AV_CODEC_ID_MJPEG, AV_CODEC_ID_H264); + OriginalInfo info(1920, 2160, mOutputFileInfo->mThumbnailFileName); // TODO: + picture.Init(info); + picture.CreateOriginalPicture(mOutputFileInfo->mFileName, data, size); + picture.UnInit(); } \ No newline at end of file diff --git a/utils/MediaBase/src/FfmpegTakePicture.h b/utils/MediaBase/src/FfmpegTakePicture.h index 2c9c684..cdb1925 100644 --- a/utils/MediaBase/src/FfmpegTakePicture.h +++ b/utils/MediaBase/src/FfmpegTakePicture.h @@ -33,13 +33,33 @@ extern "C" { #ifdef __cplusplus } #endif +#include +#include class FfmpegTakePicture : virtual public FfmpegBase { public: - FfmpegTakePicture() = default; + FfmpegTakePicture(); virtual ~FfmpegTakePicture() = default; - virtual StatusCode OpenJpegFile(const OutputFileInfo &fileInfo) override; - virtual StatusCode CloseJpegFile(void) override; - virtual StatusCode WriteJpegData(const void *data, const size_t &size) override; + StatusCode OpenJpegFile(const OutputFileInfo &fileInfo) override; + StatusCode CloseJpegFile(void) override; + /** + * @brief This function needs to return the result quickly without blocking, so as to avoid the middleware thread + * being blocked when processing a single frame of data, causing a large number of useless frames to accumulate in + * the buffer. + * @param data + * @param size + * @return StatusCode + */ + StatusCode WriteJpegData(const void *data, const size_t &size) override; + +private: + void CreateJpegFile(const void *data, const size_t &size); + void CreateJpegFileThread(const void *data, const size_t &size); + +private: + std::shared_ptr mOutputFileInfo; + bool mTaskRuning; + std::thread mCodecThread; + char *mFrameData; }; #endif \ No newline at end of file diff --git a/utils/MediaBase/src/FfmpegThumbnail.cpp b/utils/MediaBase/src/FfmpegThumbnail.cpp index 04df442..7095e42 100644 --- a/utils/MediaBase/src/FfmpegThumbnail.cpp +++ b/utils/MediaBase/src/FfmpegThumbnail.cpp @@ -26,8 +26,6 @@ extern "C" { #include #include #include -#include -#include #include #include #include @@ -138,7 +136,7 @@ void FfmpegThumbnail::GetDecodeDataCallback(AVFrame *frame) } void FfmpegThumbnail::GetEncodeDataCallback(AVPacket *pkt, const std::string &fileName) { - SaveThumbnailFile(fileName, pkt->data, pkt->size); + SavePicture(fileName, pkt->data, pkt->size); } void FfmpegThumbnail::EncodeDataToPicture(AVFrame *frame) { @@ -195,14 +193,14 @@ END: } return; } -bool FfmpegThumbnail::SaveThumbnailFile(const std::string &fileName, const void *data, const size_t &size) +bool FfmpegThumbnail::SavePicture(const std::string &fileName, const void *data, const size_t &size) { FILE *file = nullptr; if (!data) { - LogError("SaveThumbnailFile:%s failed, data is nullptr.\n", fileName.c_str()); + LogError("SavePicture:%s failed, data is nullptr.\n", fileName.c_str()); return false; } - LogInfo("SaveThumbnailFile:%s, size = %u\n", fileName.c_str(), size); + LogInfo("SavePicture:%s, size = %u\n", fileName.c_str(), size); file = fopen(fileName.c_str(), "a+"); if (!file) { LogError("fopen failed.\n"); diff --git a/utils/MediaBase/src/FfmpegThumbnail.h b/utils/MediaBase/src/FfmpegThumbnail.h index 8262d03..e5b34e7 100644 --- a/utils/MediaBase/src/FfmpegThumbnail.h +++ b/utils/MediaBase/src/FfmpegThumbnail.h @@ -61,7 +61,7 @@ protected: virtual void EncodeDataToPicture(AVFrame *frame); protected: - static bool SaveThumbnailFile(const std::string &fileName, const void *data, const size_t &size); + static bool SavePicture(const std::string &fileName, const void *data, const size_t &size); private: std::shared_ptr mEncoder; diff --git a/utils/MediaBase/src/MediaBaseImpl.h b/utils/MediaBase/src/MediaBaseImpl.h index c9b68d0..46ab694 100644 --- a/utils/MediaBase/src/MediaBaseImpl.h +++ b/utils/MediaBase/src/MediaBaseImpl.h @@ -17,9 +17,10 @@ #include "FfmpegBase.h" #include "FfmpegMuxStreamV2.h" #include "FfmpegReadFile.h" +#include "FfmpegTakePicture.h" #include "IMediaBase.h" #include -class MediaBaseImpl : public FfmpegReadFile, public FfmpegMuxStreamV2 +class MediaBaseImpl : public FfmpegReadFile, public FfmpegMuxStreamV2, public FfmpegTakePicture { public: MediaBaseImpl(const MediaHandleType &type);