Ffmpeg take picture ok.

This commit is contained in:
Fancy code 2024-07-24 11:47:44 +08:00
parent 33824829cd
commit 64f7777c5e
29 changed files with 387 additions and 50 deletions

View File

@ -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);

View File

@ -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

View File

@ -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"

View File

@ -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<MediaTaskResponse> &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;

View File

@ -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;

View File

@ -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<VMediaTaskIniator> &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<VMediaTask> task =
std::make_shared<MediaTask>(MediaTaskType::END, bindEvent, iniator, info.mSerialNumber, info.mSavingPath);
std::make_shared<MediaTask>(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;
}
}

View File

@ -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<VMediaTaskIniator> &iniator);
private:
MediaTaskType WorkModeConvert(const WorkMode &mode);
protected:
std::shared_ptr<VMediaHandle> mMediaHandle;

View File

@ -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<VMcuMonitor> McuManagerImpl::GetMcuMonitor(void)

View File

@ -92,5 +92,8 @@ public:
virtual StatusCode UnInit(void);
virtual StatusCode SetMediaMonitor(std::shared_ptr<VMediaMonitor> &monitor);
virtual StatusCode GetMediaChannel(const MediaChannel &channel, std::shared_ptr<VMediaHandle> &handle);
public:
static const char *PrintfTaskType(const MediaTaskType &type);
};
#endif

View File

@ -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";
}
}

View File

@ -16,7 +16,7 @@
#include "IHalCpp.h"
#include "ILog.h"
#include "IMediaManager.h"
#include "RecordMp4.h"
#include "MediaManagerMakePtr.h"
#include "StatusCode.h"
#include <chrono>
#include <cstdlib>
@ -80,7 +80,8 @@ StatusCode MediaHandle::ExecuteTask(std::shared_ptr<VMediaTask> &task)
return CreateStatusCode(STATUS_CODE_NOT_OK);
}
}
mStreamHandle = std::make_shared<RecordMp4>(task);
// mStreamHandle = std::make_shared<RecordMp4>(task);
mStreamHandle = MediaManagerMakePtr::GetInstance()->CreateMediaHandle(task);
if (nullptr == mStreamHandle) {
LogError("Create stream handle failed.\n");
mStreamHandle.reset();

View File

@ -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 <memory>
bool CreateMediaManagerModule(void)
{
@ -54,4 +57,25 @@ const StatusCode MediaManagerMakePtr::CreateMediaManagerModule(std::shared_ptr<I
auto tmp = std::make_shared<MediaManagerImpl>();
impl = tmp;
return CreateStatusCode(STATUS_CODE_OK);
}
std::shared_ptr<VStreamHandle> MediaManagerMakePtr::CreateMediaHandle(std::shared_ptr<VMediaTask> &task)
{
const MediaTaskType type = task->GetTaskType();
std::shared_ptr<VStreamHandle> stream;
switch (type) {
case MediaTaskType::TAKE_PICTURE:
stream = std::make_shared<TakePicture>(task);
break;
case MediaTaskType::TAKE_VIDEO:
stream = std::make_shared<RecordMp4>(task);
break;
case MediaTaskType::TAKE_PICTURE_AND_VIDEO:
/* code */
break;
default:
LogWarning("unsupport type.\n");
break;
}
return stream;
}

View File

@ -16,6 +16,7 @@
#define MEDIA_MANAGER_MAKE_PTR_H
#include "IMediaManager.h"
#include "StatusCode.h"
#include "VStreamHandle.h"
#include <memory>
class MediaManagerMakePtr
{
@ -24,5 +25,6 @@ public:
virtual ~MediaManagerMakePtr() = default;
static std::shared_ptr<MediaManagerMakePtr> &GetInstance(std::shared_ptr<MediaManagerMakePtr> *impl = nullptr);
virtual const StatusCode CreateMediaManagerModule(std::shared_ptr<IMediaManager> &impl);
virtual std::shared_ptr<VStreamHandle> CreateMediaHandle(std::shared_ptr<VMediaTask> &task);
};
#endif // !MEDIA_MANAGER_MAKE_PTR_H

View File

@ -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 <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <mutex>
#include <string.h>
#include <string>
#include <utility>
#include <vector>
TakePicture::TakePicture(std::shared_ptr<VMediaTask> &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<std::mutex> 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<std::mutex> locker(mMutex);
if (mTakePictureObject) {
IWriteJpegData(mTakePictureObject, stream, length);
}
}
StatusCode TakePicture::GetAllFiles(std::vector<MediaTaskResponse> &files)
{
files = std::move(mTaskResponse);
mTaskResponse.clear();
return CreateStatusCode(STATUS_CODE_OK);
}
bool TakePicture::HandleFinished(void)
{
return mIsTakePictureFinished == OUTPUT_FILE_STATUS_FINISHED ? true : false;
}

View File

@ -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 <cstdio>
#include <mutex>
#include <vector>
class TakePicture : public VStreamHandle
{
public:
TakePicture(std::shared_ptr<VMediaTask> &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<MediaTaskResponse> &files) override;
bool HandleFinished(void) override;
private:
std::mutex mMutex; // TODO: To improve and delete this mutex.
void *mTakePictureObject;
std::shared_ptr<VMediaTask> mPictureTask;
std::vector<MediaTaskResponse> mTaskResponse;
int mIsTakePictureFinished;
};
#endif

View File

@ -19,33 +19,33 @@
#include <vector>
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<MediaTaskResponse> &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;
}

View File

@ -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")

View File

@ -15,6 +15,7 @@
#include "HuntingCameraTest.h"
#include "GtestUsing.h"
#include "ILog.h"
#include "IpcConfigTestTool.h"
#include "MainThread.h"
#include <thread>
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();
}

View File

@ -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:

View File

@ -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)
{

View File

@ -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);

View File

@ -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 <libavcodec/codec_id.h>
#include <libavcodec/packet.h>
#include <libavformat/avformat.h>
#include <libavutil/frame.h>
#ifdef __cplusplus
}
#endif
#include <cstddef>
#include <functional>
#include <memory>
#include <string>
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<original_info>(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);
}

View File

@ -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<FfmpegEncoder> mEncoder;
std::function<void(AVPacket *)> mEncodeCallback;
std::shared_ptr<OriginalInfo> mPictureInfo;
};
#endif

View File

@ -15,7 +15,6 @@
#include "FfmpegOutputStream.h"
#include "FfmpegDecoder.h"
#include "FfmpegEncoder.h"
#include "FfmpegOriginalPicture.h"
#include "FfmpegThumbnail.h"
#include "ILog.h"
#include <stdio.h>
@ -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");
}

View File

@ -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 <memory>
#ifdef __cplusplus
extern "C" {
#endif
#include <libavcodec/codec_id.h>
#ifdef __cplusplus
}
#endif
#include <cstdlib>
#include <string.h>
#include <thread>
FfmpegTakePicture::FfmpegTakePicture() : mOutputFileInfo(nullptr), mTaskRuning(false), mFrameData(nullptr)
{
}
StatusCode FfmpegTakePicture::OpenJpegFile(const OutputFileInfo &fileInfo)
{
return CreateStatusCode(STATUS_CODE_OK);
mOutputFileInfo = std::make_shared<OutputFileInfo>(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<int>(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<FfmpegTakePicture> output, const void *frameData, const size_t dataSize) {
LogInfo("CreateJpegFile start.\n");
output->CreateJpegFileThread(frameData, dataSize);
};
std::shared_ptr<FfmpegTakePicture> impl =
std::dynamic_pointer_cast<FfmpegTakePicture>(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();
}

View File

@ -33,13 +33,33 @@ extern "C" {
#ifdef __cplusplus
}
#endif
#include <memory>
#include <thread>
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<OutputFileInfo> mOutputFileInfo;
bool mTaskRuning;
std::thread mCodecThread;
char *mFrameData;
};
#endif

View File

@ -26,8 +26,6 @@ extern "C" {
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <libavutil/avutil.h>
#include <libavutil/dict.h>
#include <libavutil/error.h>
#include <libavutil/frame.h>
#include <libavutil/imgutils.h>
#include <libavutil/mem.h>
@ -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");

View File

@ -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<FfmpegEncoder> mEncoder;

View File

@ -17,9 +17,10 @@
#include "FfmpegBase.h"
#include "FfmpegMuxStreamV2.h"
#include "FfmpegReadFile.h"
#include "FfmpegTakePicture.h"
#include "IMediaBase.h"
#include <thread>
class MediaBaseImpl : public FfmpegReadFile, public FfmpegMuxStreamV2
class MediaBaseImpl : public FfmpegReadFile, public FfmpegMuxStreamV2, public FfmpegTakePicture
{
public:
MediaBaseImpl(const MediaHandleType &type);