opencv+mpp硬编码采集视频保存文件 QT代码
时间: 2023-10-01 14:11:36 浏览: 308
以下是基于OpenCV和MPP进行视频采集和硬编码保存的示例代码,采用QT C++编写:
```c++
#include <opencv2/opencv.hpp>
#include <rockchip/rk_mpi.h>
#include <rockchip/mpp_buffer.h>
using namespace cv;
// 定义视频输入参数
#define VIDEO_WIDTH 1280
#define VIDEO_HEIGHT 720
#define VIDEO_FPS 30
#define VIDEO_BPS 8000000
#define VIDEO_GOP 30
// 定义编码器参数
#define ENCODER_NAME "h264enc"
#define ENCODER_WIDTH VIDEO_WIDTH
#define ENCODER_HEIGHT VIDEO_HEIGHT
#define ENCODER_FPS VIDEO_FPS
#define ENCODER_GOP VIDEO_GOP
#define ENCODER_BITRATE VIDEO_BPS
class VideoRecorder : public QObject
{
Q_OBJECT
public:
VideoRecorder(QObject* parent = nullptr);
~VideoRecorder();
void start();
void stop();
signals:
void finished();
private:
void encodeFrame(const Mat& frame);
private:
MPP_ENC_CONFIG_S enc_cfg_;
MPP_ENC_HANDLE hEnc_;
VideoCapture cap_;
VideoWriter writer_;
bool is_running_;
};
VideoRecorder::VideoRecorder(QObject* parent) : QObject(parent), is_running_(false)
{
// 初始化MPP环境
RK_MPI_SYS_Init();
// 创建编码器
memset(&enc_cfg_, 0, sizeof(enc_cfg_));
enc_cfg_.eType = MPP_VIDEO_CodingAVC;
enc_cfg_.iUsage = MPP_ENC_NORMAL;
enc_cfg_.iPicWidth = ENCODER_WIDTH;
enc_cfg_.iPicHeight = ENCODER_HEIGHT;
enc_cfg_.iKeyInterval = ENCODER_GOP;
enc_cfg_.fFrameRate = ENCODER_FPS;
enc_cfg_.iBitRate = ENCODER_BITRATE;
RK_MPI_VENC_Create(&hEnc_, &enc_cfg_);
// 创建输入视频流
cap_.set(CAP_PROP_FRAME_WIDTH, VIDEO_WIDTH);
cap_.set(CAP_PROP_FRAME_HEIGHT, VIDEO_HEIGHT);
cap_.set(CAP_PROP_FPS, VIDEO_FPS);
// 创建输出文件
writer_.open("output.mp4", VideoWriter::fourcc('a', 'v', 'c', '1'), VIDEO_FPS, Size(VIDEO_WIDTH, VIDEO_HEIGHT), true);
}
VideoRecorder::~VideoRecorder()
{
// 释放资源
writer_.release();
RK_MPI_VENC_Destroy(hEnc_);
RK_MPI_SYS_Exit();
}
void VideoRecorder::start()
{
is_running_ = true;
// 循环采集视频帧并编码保存
while (is_running_)
{
Mat frame;
cap_.read(frame);
encodeFrame(frame);
}
emit finished();
}
void VideoRecorder::stop()
{
is_running_ = false;
}
void VideoRecorder::encodeFrame(const Mat& frame)
{
MPP_BUFFER buffer;
RK_MPI_MBPOOL pool = NULL;
RK_MPI_MBPOOL_CREATE(&pool, MPP_BUFFER_TYPE_ION, 1, ENCODER_WIDTH*ENCODER_HEIGHT*3/2);
RK_MPI_MBPOOL_GET_BUFFER(pool, &buffer, RK_TRUE);
RK_MPI_MB_BLK blk = RK_MPI_MB_GetPtr(buffer);
memcpy(blk->pVirAddr, frame.data, VIDEO_WIDTH*VIDEO_HEIGHT*3/2);
blk->u32Size = VIDEO_WIDTH*VIDEO_HEIGHT*3/2;
MPP_PACKET packet;
memset(&packet, 0, sizeof(packet));
RK_MPI_VENC_SendFrame(hEnc_, buffer, &packet);
if (packet != NULL)
{
writer_.write(packet->pData, packet->iDataSize);
RK_MPI_SYS_FreePacket(packet);
}
RK_MPI_MBPOOL_PUT_BUFFER(pool, buffer);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
VideoRecorder recorder;
recorder.start();
QObject::connect(&recorder, &VideoRecorder::finished, &a, &QCoreApplication::quit);
return a.exec();
}
```
以上代码仅作为示例,具体实现过程需要根据您的具体需求进行调整和优化。另外,需要注意的是,由于硬编码需要使用MPP库,因此需要将相关头文件和库文件链接到项目中。
阅读全文