生成一个使用qt下 jpeg图片使用rockchip rmmpp 硬件编码器 输出h264格式用ffmpeg推流出去
时间: 2023-06-15 18:03:16 浏览: 97
这是一个比较复杂的任务,需要使用到一些专业的技能和工具。以下是大致的步骤:
1. 使用 Qt 中的函数加载 JPEG 图片并将其转换为 YUV 格式的数据。
2. 将 YUV 数据传输到 Rockchip RMMPP 硬件编码器,使用硬件编码器将 YUV 数据编码为 H.264 格式的视频流。
3. 使用 FFmpeg 将编码后的 H.264 视频流推送到网络上。
具体实现步骤如下:
1. 加载 JPEG 图片并将其转换为 YUV 格式的数据。可以使用 Qt 中的 QImage 类和其转换函数来实现。
```cpp
QImage image("test.jpg");
QByteArray imageData;
QBuffer buffer(&imageData);
buffer.open(QIODevice::ReadWrite);
image.save(&buffer, "JPEG");
// 转换为 YUV 格式
int width = image.width();
int height = image.height();
int size = width * height * 3 / 2; // YUV 数据的大小
unsigned char* yuvData = new unsigned char[size];
libyuv::ConvertFromI420((const uint8_t*)buffer.data().data(), buffer.data().size(),
yuvData, width,
yuvData + width * height, width / 2,
yuvData + width * height * 5 / 4, width / 2,
0, 0, // 无需旋转
width, height,
width, height,
libyuv::kRotate0, libyuv::FOURCC_I420);
```
2. 将 YUV 数据传输到 Rockchip RMMPP 硬件编码器,使用硬件编码器将 YUV 数据编码为 H.264 格式的视频流。
首先需要初始化 Rockchip RMMPP 硬件编码器,然后将 YUV 数据传输到硬件编码器中,进行编码。
```cpp
// 初始化硬件编码器
MPP_RET ret = MPP_OK;
MppCtx mpp_ctx = NULL;
MppApi *mpi = NULL;
MppCodingType coding_type = MPP_VIDEO_CodingAVC;
MppParam param;
ret = mpp_create(&mpp_ctx, &mpi);
if (ret != MPP_OK) {
qDebug() << "mpp_create failed!";
return;
}
// 设置编码器参数
MppEncPrepCfg prep_cfg;
MppEncRcCfg rc_cfg;
MppEncH264Cfg h264_cfg;
memset(&prep_cfg, 0, sizeof(prep_cfg));
prep_cfg.change = MPP_ENC_PREP_CFG_CHANGE_INPUT |
MPP_ENC_PREP_CFG_CHANGE_FORMAT |
MPP_ENC_PREP_CFG_CHANGE_ROTATION;
prep_cfg.width = width;
prep_cfg.height = height;
prep_cfg.format = MPP_FMT_YUV420SP;
prep_cfg.rotation = MPP_ENC_ROT_0;
memset(&rc_cfg, 0, sizeof(rc_cfg));
rc_cfg.change = MPP_ENC_RC_CFG_CHANGE_RC_MODE;
rc_cfg.rc_mode = MPP_ENC_RC_MODE_CBR;
memset(&h264_cfg, 0, sizeof(h264_cfg));
h264_cfg.change = MPP_ENC_H264_CFG_CHANGE_PROFILE |
MPP_ENC_H264_CFG_CHANGE_ENTROPY |
MPP_ENC_H264_CFG_CHANGE_TRANS_8x8 |
MPP_ENC_H264_CFG_CHANGE_QP_LIMIT;
h264_cfg.profile = MPP_PROFILE_H264_HIGH;
h264_cfg.entropy_coding_mode = 1; // CABAC
h264_cfg.transform8x8_mode = 1;
h264_cfg.qp_max = 40;
h264_cfg.qp_min = 20;
h264_cfg.qp_max_step = 4;
param = &prep_cfg;
mpi->control(mpp_ctx, MPP_ENC_SET_PREP_CFG, param);
param = &rc_cfg;
mpi->control(mpp_ctx, MPP_ENC_SET_RC_CFG, param);
param = &h264_cfg;
mpi->control(mpp_ctx, MPP_ENC_SET_CODEC_CFG, param);
ret = mpi->init(mpp_ctx, MPP_CTX_ENC, coding_type);
if (ret != MPP_OK) {
qDebug() << "mpi->init failed!";
return;
}
// 传输 YUV 数据到硬件编码器
MppBuffer yuv_buf = NULL;
MppBuffer packet_buf = NULL;
MppFrame frame = NULL;
MppPacket packet = NULL;
ret = mpp_buffer_get(mpp_ctx, &yuv_buf, size);
if (ret != MPP_OK) {
qDebug() << "mpp_buffer_get yuv_buf failed!";
return;
}
memcpy((void*)mpp_buffer_get_ptr(yuv_buf), yuvData, size);
ret = mpi->poll(mpp_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK);
if (ret != MPP_OK) {
qDebug() << "mpi->poll input failed!";
return;
}
ret = mpi->dequeue(mpp_ctx, MPP_PORT_INPUT, &frame);
if (ret != MPP_OK) {
qDebug() << "mpi->dequeue input failed!";
return;
}
frame->width = width;
frame->height = height;
frame->hor_stride = width;
frame->ver_stride = height;
frame->buf[0] = yuv_buf;
frame->buf[1] = frame->buf[0] + width * height;
frame->buf[2] = frame->buf[1] + width * height / 4;
ret = mpi->enqueue(mpp_ctx, MPP_PORT_INPUT, frame);
if (ret != MPP_OK) {
qDebug() << "mpi->enqueue input failed!";
return;
}
ret = mpi->poll(mpp_ctx, MPP_PORT_OUTPUT, MPP_POLL_BLOCK);
if (ret != MPP_OK) {
qDebug() << "mpi->poll output failed!";
return;
}
ret = mpi->dequeue(mpp_ctx, MPP_PORT_OUTPUT, &packet);
if (ret != MPP_OK) {
qDebug() << "mpi->dequeue output failed!";
return;
}
// 获取编码后的数据
unsigned char* h264Data = new unsigned char[packet->length];
memcpy(h264Data, mpp_packet_get_data(packet), packet->length);
```
3. 使用 FFmpeg 将编码后的 H.264 视频流推送到网络上。
首先需要初始化 FFmpeg,然后将编码后的 H.264 视频流写入到 FFmpeg 的 AVPacket 中,并使用 FFmpeg 将 AVPacket 推送到网络上。
```cpp
// 初始化 FFmpeg
av_register_all();
avformat_network_init();
AVFormatContext* fmt_ctx = NULL;
avformat_alloc_output_context2(&fmt_ctx, NULL, "flv", "rtmp://xxx.xxx.xxx.xxx:1935/live");
AVOutputFormat* fmt = fmt_ctx->oformat;
AVStream* video_stream = avformat_new_stream(fmt_ctx, NULL);
AVCodec* codec = avcodec_find_encoder_by_name("libx264");
AVCodecContext* codec_ctx = avcodec_alloc_context3(codec);
codec_ctx->codec_id = AV_CODEC_ID_H264;
codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
codec_ctx->width = width;
codec_ctx->height = height;
codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
codec_ctx->time_base = { 1, 25 };
codec_ctx->bit_rate = 500000;
avcodec_open2(codec_ctx, codec, NULL);
video_stream->codecpar->codec_id = AV_CODEC_ID_H264;
video_stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
video_stream->codecpar->width = width;
video_stream->codecpar->height = height;
video_stream->codecpar->format = codec_ctx->pix_fmt;
video_stream->codecpar->bit_rate = codec_ctx->bit_rate;
video_stream->time_base = codec_ctx->time_base;
avformat_write_header(fmt_ctx, NULL);
// 推送编码后的视频流到网络
AVPacket pkt;
av_init_packet(&pkt);
pkt.data = h264Data;
pkt.size = packet->length;
pkt.stream_index = video_stream->index;
av_write_frame(fmt_ctx, &pkt);
av_write_trailer(fmt_ctx);
avcodec_free_context(&codec_ctx);
avformat_free_context(fmt_ctx);
```
这样,就完成了使用 Qt、Rockchip RMMPP 硬件编码器和 FFmpeg 将 JPEG 图片编码为 H.264 格式并推送到网络上的任务。
相关推荐
![cpp](https://img-home.csdnimg.cn/images/20210720083646.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)