#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <queue>
#include <opencv2/opencv.hpp>
/*
* 定义一些输入量
* FramInputPerSecond 输入源视频获取帧数
* FramInputInterval 转化成时间间隔
* TimeoutThreshold 帧过期丢弃阈值
*/
#define FramInputPerSecond 15
#define FramInputInterval 1000/FramInputPerSecond
#define TimeoutThreshold 50
class _fram
{
public:
_fram(cv::Mat mat, std::chrono::system_clock::time_point tp) : framContent(mat), tp(tp){};
~_fram(){};
cv::Mat framContent;
std::chrono::system_clock::time_point tp;
};
std::mutex lock;
std::queue<_fram> framBuffer;
int playMedia(){
double framTpInterval; // ms time between two fram;
while (true)
{
while (framBuffer.empty())
{
std::this_thread::sleep_for(std::chrono::milliseconds(40));
std::cout<<"wait for image"<<std::endl;
}
//cv::imshow("buffer",framBuffer.front().framContent);
//假设需要20ms计算图像
//模拟读取数据
cv::Mat cal = framBuffer.front().framContent;
//计算读取帧与模拟计算
framTpInterval = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - framBuffer.front().tp).count();
std::cout<<framTpInterval<<std::endl;
if (framTpInterval > TimeoutThreshold)
std::cout<< framTpInterval <<" 延迟!丢弃帧!"<<std::endl;
else
std::this_thread::sleep_for(std::chrono::milliseconds(10));
framBuffer.pop();
}
}
int main(){
cv::VideoCapture v;
v.open("v4l2src device=/dev/video0 ! image/jpeg,width=1280,height=720 ! jpegdec ! appsink",
cv::CAP_GSTREAMER);
if (!v.isOpened())
{
std::cout<<"Wrong Open Camera"<<std::endl;
return -1;
}
std::thread T_playMedia(playMedia);
/*
* 主线程读取视频输入
* 并存入到缓冲区中
*/
while (true)
{
cv::Mat framTmp;
std::chrono::system_clock::time_point t1 = std::chrono::system_clock::now();
v.read(framTmp);
framBuffer.emplace(framTmp, std::chrono::system_clock::now());
std::chrono::system_clock::time_point t2 = std::chrono::system_clock::now();
//std::cout<<std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count()<<std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(FramInputInterval));
}
}