diff --git a/middleware/MediaManager/src/MediaHandle.cpp b/middleware/MediaManager/src/MediaHandle.cpp index 7214edb..8da4a6a 100644 --- a/middleware/MediaManager/src/MediaHandle.cpp +++ b/middleware/MediaManager/src/MediaHandle.cpp @@ -19,11 +19,19 @@ #include "RecordMp4.h" #include "StatusCode.h" #include +#include #include #include #include +#include #include #include +one_frame_stream::one_frame_stream() : mType(FrameType::END), mData(nullptr), mLength(0) +{ +} +one_frame_stream::~one_frame_stream() +{ +} MediaHandle::MediaHandle(const MediaChannel &mediaChannel, const std::shared_ptr &cameraHal) : mMediaChannel(mediaChannel), mCameraHal(cameraHal), mTaskRuning(false) { @@ -42,10 +50,14 @@ void MediaHandle::Init(void) void MediaHandle::UnInit(void) { mTaskRuning = false; - mCv.notify_one(); + mCvTaskHandle.notify_one(); + mCvFrameHandle.notify_one(); if (mTaskTimerThread.joinable()) { mTaskTimerThread.join(); } + if (mFrameHandleThread.joinable()) { + mFrameHandleThread.join(); + } if (mCameraHal) { /** * @brief Before releasing the class instance, it is necessary to call the UnInit function to ensure that the @@ -83,6 +95,7 @@ StatusCode MediaHandle::ExecuteTask(std::shared_ptr &task) if (IsCodeOK(code)) { mCurrentTask = task; StartTaskTimer(); + StartFrameHandle(); } else { LogError("Execute task failed.\n"); @@ -112,7 +125,7 @@ void MediaHandle::TaskTimer(void) mTaskRuning = true; while (mTaskRuning) { std::unique_lock lock(mMutex); - mCv.wait_for(lock, std::chrono::milliseconds(TASK_TIMER), [&] { + mCvTaskHandle.wait_for(lock, std::chrono::milliseconds(TASK_TIMER), [&] { return !mTaskRuning; }); /** @@ -139,15 +152,75 @@ void MediaHandle::TaskTimer(void) mCurrentTask.reset(); mMutex.unlock(); } +void MediaHandle::StartFrameHandle(void) +{ + auto taskTimerThread = [=](std::shared_ptr media) { + LogInfo("StartFrameHandle start.\n"); + media->FrameHandle(); + }; + std::shared_ptr media = shared_from_this(); + mFrameHandleThread = std::thread(taskTimerThread, media); +} +void MediaHandle::FrameHandle(void) +{ + constexpr int TASK_TIMER = 1000 * 1000; + mTaskRuning = true; + while (mTaskRuning) { + std::unique_lock lock(mMutex); + mCvFrameHandle.wait_for(lock, std::chrono::milliseconds(TASK_TIMER), [&] { + return !mTaskRuning || !mFrameList.empty(); + }); + if (mFrameList.size() > 0) { + HandleListFrame(); + } + } +} +void MediaHandle::HandleListFrame(void) +{ + int leftFrameCount = -1; + do { + OneFrameStream &frontFrame = mFrameList.front(); + OneFrameStream handleIt; + handleIt.mData = frontFrame.mData; + handleIt.mLength = frontFrame.mLength; + handleIt.mType = frontFrame.mType; + mFrameList.pop_front(); + if (FrameType::VIDEO == handleIt.mType) { + mStreamHandle->GetVideoStream(handleIt.mData, handleIt.mLength, 0); + } + if (FrameType::AUDIO == handleIt.mType) { + mStreamHandle->GetAudioStream(handleIt.mData, handleIt.mLength, 0); + } + free(handleIt.mData); + handleIt.mData = nullptr; + leftFrameCount = mFrameList.size(); + } while (leftFrameCount > 0); +} 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); + std::unique_lock lock(mMutex); + // mStreamHandle->GetVideoStream(stream, length, timeStamp); + OneFrameStream addFrame; + addFrame.mData = malloc(length); + addFrame.mLength = length; + memcpy(addFrame.mData, stream, length); + addFrame.mType = FrameType::VIDEO; + mFrameList.push_back(addFrame); + mCvFrameHandle.notify_one(); } void MediaHandle::GetAudioStreamCallback(const void *stream, const int &length, const unsigned long long &timeStamp) { - mStreamHandle->GetAudioStream(stream, length, timeStamp); + std::unique_lock lock(mMutex); + // mStreamHandle->GetAudioStream(stream, length, timeStamp); + OneFrameStream addFrame; + addFrame.mData = malloc(length); + addFrame.mLength = length; + memcpy(addFrame.mData, stream, length); + addFrame.mType = FrameType::AUDIO; + mFrameList.push_back(addFrame); + mCvFrameHandle.notify_one(); } \ No newline at end of file diff --git a/middleware/MediaManager/src/MediaHandle.h b/middleware/MediaManager/src/MediaHandle.h index ecc733f..04ec1fb 100644 --- a/middleware/MediaManager/src/MediaHandle.h +++ b/middleware/MediaManager/src/MediaHandle.h @@ -18,11 +18,26 @@ #include "IMediaManager.h" #include "VStreamHandle.h" #include +#include #include #include using std::placeholders::_1; using std::placeholders::_2; using std::placeholders::_3; +enum class FrameType +{ + VIDEO, + AUDIO, + END +}; +typedef struct one_frame_stream +{ + one_frame_stream(); + ~one_frame_stream(); + FrameType mType; + void *mData; + int mLength; +} OneFrameStream; class MediaHandle : public VMediaHandle, public std::enable_shared_from_this { public: @@ -39,18 +54,24 @@ protected: private: void StartTaskTimer(void); void TaskTimer(void); + void StartFrameHandle(void); + void FrameHandle(void); + void HandleListFrame(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; + std::condition_variable mCvTaskHandle; + std::condition_variable mCvFrameHandle; const MediaChannel &mMediaChannel; std::shared_ptr mCameraHal; std::weak_ptr mCurrentTask; std::shared_ptr mStreamHandle; bool mTaskRuning; std::thread mTaskTimerThread; + std::thread mFrameHandleThread; + std::list mFrameList; }; #endif \ No newline at end of file diff --git a/middleware/MediaManager/src/RecordMp4.cpp b/middleware/MediaManager/src/RecordMp4.cpp index bd06f1d..625ac04 100644 --- a/middleware/MediaManager/src/RecordMp4.cpp +++ b/middleware/MediaManager/src/RecordMp4.cpp @@ -21,7 +21,9 @@ #include #include #include +#include #include +#include #include RecordMp4::RecordMp4(std::shared_ptr &recordTask) : mRecordMp4Object(nullptr), mRecordTask(recordTask) { diff --git a/middleware/MediaManager/src/VStreamHandle.cpp b/middleware/MediaManager/src/VStreamHandle.cpp index 0efed77..5cfe5e3 100644 --- a/middleware/MediaManager/src/VStreamHandle.cpp +++ b/middleware/MediaManager/src/VStreamHandle.cpp @@ -14,6 +14,7 @@ */ #include "VStreamHandle.h" #include "ILog.h" +#include "IMediaManager.h" #include "StatusCode.h" #include StatusCode VStreamHandle::Init(void) diff --git a/test/support_test/video.h264 b/test/support_test/video.h264 index db50cf1..5834918 100755 Binary files a/test/support_test/video.h264 and b/test/support_test/video.h264 differ diff --git a/utils/MediaBase/src/FfmpegDecoder.cpp b/utils/MediaBase/src/FfmpegDecoder.cpp index 9932ebd..cd97a01 100644 --- a/utils/MediaBase/src/FfmpegDecoder.cpp +++ b/utils/MediaBase/src/FfmpegDecoder.cpp @@ -132,10 +132,6 @@ void FfmpegDecoder::DecodeData(const void *data, const size_t &size, std::functi if (callback) { callback(mFrame); } - // mFrame->pts = mAudioSt.next_pts; - // mAudioSt.next_pts += mFrame->nb_samples; - // ConvertAudioFrame(mFrame, mAudioSt.enc, &mAudioSt); - // write_frame(mOc, mAudioSt.enc, mAudioSt.st, mAudioSt.frame, mAudioSt.tmp_pkt); break; } av_packet_unref(packet); diff --git a/utils/MediaBase/src/FfmpegEncoder.cpp b/utils/MediaBase/src/FfmpegEncoder.cpp index e34a1ff..1962242 100644 --- a/utils/MediaBase/src/FfmpegEncoder.cpp +++ b/utils/MediaBase/src/FfmpegEncoder.cpp @@ -82,7 +82,6 @@ bool FfmpegEncoder::Init(int &outputFlags) } mCodecCtx->sample_rate = 8000; av_channel_layout_copy(&mCodecCtx->ch_layout, &src); - // st->time_base = (AVRational){1, mCodecCtx->sample_rate}; break; case AVMEDIA_TYPE_VIDEO: @@ -96,7 +95,6 @@ bool FfmpegEncoder::Init(int &outputFlags) * of which frame timestamps are represented. For fixed-fps content, * timebase should be 1/framerate and timestamp increments should be * identical to 1. */ - // st->time_base = (AVRational){1, STREAM_FRAME_RATE}; mCodecCtx->time_base = (AVRational){1, STREAM_FRAME_RATE}; mCodecCtx->gop_size = 12; /* emit one intra frame every twelve frames at most */ @@ -202,19 +200,9 @@ int FfmpegEncoder::EncodeData(AVFrame *frame, AVStream *stream, std::functiontime_base, stream->time_base); mTmpPkt->stream_index = stream->index; - /* Write the compressed frame to the media file. */ - // log_packet(fmt_ctx, pkt); - // ret = av_interleaved_write_frame(fmt_ctx, pkt); if (callback) { callback(mTmpPkt); } - /* pkt is now blank (av_interleaved_write_frame() takes ownership of - * its contents and resets pkt), so that no unreferencing is necessary. - * This would be different if one used av_write_frame(). */ - // if (ret < 0) { - // fprintf(stderr, "Error while writing output packet: %s\n", av_err2str(ret)); - // return AVERROR_EXIT; - // } } return ret == AVERROR_EOF ? 1 : 0;