生成一个qt下用opencv的Mat格式图片通过rkmpp编码成h264,并通过rtsp推流的程序
时间: 2024-05-05 18:21:35 浏览: 273
以下是一个Qt下使用OpenCV的Mat格式图片通过RK3399的硬件编码器RKMPP编码成H.264并通过RTSP推流的程序示例。
```cpp
#include <QCoreApplication>
#include <opencv2/opencv.hpp>
#include <rockchip/rk_mpi.h>
#include <rockchip/rk_mpp.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 初始化RKMPP
MPP_RET ret = mpp_env_init();
if (ret != MPP_OK) {
printf("mpp_env_init failed!\n");
return -1;
}
// 创建编码器
MppCtx ctx;
ret = mpp_create(&ctx, MPP_CTX_ENC);
if (ret != MPP_OK) {
printf("mpp_create failed!\n");
return -1;
}
// 配置编码器参数
MppApi *mpi = mpp_get_api(ctx);
MppEncPrepCfg prep_cfg;
prep_cfg.change = MPP_ENC_PREP_CFG_CHANGE_INPUT |
MPP_ENC_PREP_CFG_CHANGE_FORMAT;
prep_cfg.width = 640;
prep_cfg.height = 480;
prep_cfg.format = MPP_FMT_YUV420P;
mpi->control(ctx, MPP_ENC_SET_PREP_CFG, &prep_cfg);
MppEncCodecCfg codec_cfg;
codec_cfg.coding = MPP_VIDEO_CodingAVC;
codec_cfg.rc_mode = MPP_ENC_RC_MODE_CBR;
codec_cfg.fps_in = 30;
codec_cfg.fps_out = 30;
codec_cfg.profile = MPP_PROFILE_AVC_MAIN;
codec_cfg.level = MPP_LEVEL_UNKNOWN;
codec_cfg.target_bitrate = 1000000;
codec_cfg.qp_init = 26;
codec_cfg.qp_max = 48;
codec_cfg.qp_min = 20;
mpi->control(ctx, MPP_ENC_SET_CODEC_CFG, &codec_cfg);
// 初始化编码器
ret = mpi->init(ctx);
if (ret != MPP_OK) {
printf("mpi->init failed!\n");
return -1;
}
// 打开RTSP推流
cv::VideoWriter writer;
writer.open("rtsp://localhost:8554/test.sdp", cv::CAP_FFMPEG,
cv::VideoWriter::fourcc('H', '2', '6', '4'), 30,
cv::Size(640, 480), true);
// 加载测试图片
cv::Mat image = cv::imread("test.jpg");
if (image.empty()) {
printf("Failed to load image!\n");
return -1;
}
// 创建输入YUV内存
MppFrame frame;
ret = mpi->control(ctx, MPP_ENC_GET_EXTRA_INFO, &frame);
if (ret != MPP_OK) {
printf("mpi->control failed!\n");
return -1;
}
frame->width = 640;
frame->height = 480;
frame->hor_stride = 640;
frame->ver_stride = 480;
frame->fmt = MPP_FMT_YUV420P;
mpp_frame_init(frame);
// 创建输出H.264内存
MppBuffer packet_buf;
mpp_buffer_get(ctx, &packet_buf, 4 * 1024 * 1024);
MppPacket packet;
mpp_packet_init(&packet, packet_buf);
// 编码YUV图像
for (int i = 0; i < 100; i++) {
// 将OpenCV的Mat格式转换为YUV格式
cv::Mat yuv_image;
cv::cvtColor(image, yuv_image, cv::COLOR_BGR2YUV_I420);
// 将YUV图像写入输入YUV内存
uint8_t *buf = (uint8_t *)mpp_buffer_get_ptr(frame->buf);
memcpy(buf, yuv_image.data, 640 * 480 * 3 / 2);
// 编码YUV图像
ret = mpi->encode_put_frame(ctx, frame, NULL);
if (ret != MPP_OK) {
printf("mpi->encode_put_frame failed!\n");
return -1;
}
// 获取编码后的H.264数据
ret = mpi->encode_get_packet(ctx, &packet);
if (ret != MPP_OK) {
printf("mpi->encode_get_packet failed!\n");
return -1;
}
// 将H.264数据写入RTSP推流
writer.write(packet->data, packet->length);
}
// 释放资源
writer.release();
mpp_packet_deinit(&packet);
mpp_buffer_put(packet_buf);
mpp_frame_deinit(&frame);
mpi->reset(ctx);
mpi->control(ctx, MPP_ENC_SET_IDR_FRAME, NULL);
mpi->destroy(ctx);
mpp_env_deinit();
return 0;
}
```
需要注意的几点:
1. 该示例程序使用的是Rockchip的RKMPP编码器。如果使用的是其他厂商的编码器,代码可能会有所不同。
2. 在编码器初始化时,需要设置编码器的参数。例如,设置编码器的分辨率、码率、帧率等。
3. 将OpenCV的Mat格式图像转换为YUV格式,并写入输入YUV内存。
4. 在编码器中,将输入YUV内存编码为H.264格式,并将编码后的数据写入输出H.264内存。
5. 将输出H.264内存的数据写入RTSP推流。在这个示例中,使用了OpenCV的VideoWriter类来实现RTSP推流。
6. 在程序结束前,需要释放所有资源。
阅读全文